❤️❤️前言~🥳🎉🎉🎉
hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥💥,如果发现这篇文章有问题的话,欢迎各位评论留言指正,大家一起加油!一起chin up!👍👍
💥个人主页:E绵绵的博客
💥所属专栏:JAVASE题目练习 JAVASE知识点专栏 c语言知识点专栏 c语言题目练习
之前我们在讲类和对象时就提到过内部类,不过当时说了等讲完抽象类和接口再讲这个,现在兑现诺言的时候到了,那我们开始内部类的学习吧!
内部类
❤️❤️内部类是指在一个类的内部定义的另一个类。内部类可以访问外部类的所有成员,包括私有成员。内部类提供了一种封装和组织代码的方式,可以将相关的类和接口放在一起,增加代码的可读性和可维护性。
分为以下四种:
实例(成员)内部类,静态内部类,局部(方法)内部类,匿名内部类。
内部类虽然在外部类里面,但是它编译时内部类会形成单独的字节码文件
实例内部类
❤️❤️实例内部类的成员变量和成员方法都不能用static修饰。
但存在一个特殊的点:实例内部类中的成员变量也可以用static修饰,只不过那必须加上final修饰使其变为常量才可以用static修饰。
❤️❤️我们要清楚虽然内部类在外部类里面,但实例化外部类并不会同时实例出内部类,所以当实例出外部类后,内部类需要我们主动实例化。
所以实例内部类的实例化需要先创建外部类的实例,然后再通过外部类的实例来创建实例内部类的对象。
例如,如果外部类是Outer,实例内部类是Inner,那么可以通过Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); 来实例化实例内部类.
当然还有另外一种方式也可以实例化实例内部类:Outer.Inner inner=new Outer().new lnner();
❤️❤️在实例内部类中我们可以访问外部类的所有成员,包括私有成员。具体细节如下:
1. 🎯🎯当外部类和内部类成员不同名时,我们可以在实例内部类中直接使用外部类的成员变量和成员方法,无需前面还要引用:
在上图中InnerClass是实例内部类,我们在该内部类中直接使用了外部类中的成员变量a,但切记注意这里的a前面不能带this,如果带了this就表示这是内部类中的a,但我们内部类中不存在同名的a,所以报错。不带this直接用a时因为内部类没a所以就表示这是外部类中的a。
成员方法跟成员变量同理。
2. 🎯🎯而当内部类和外部类存在同名的成员变量时,内部类直接使用它时会优先选择自己的成员变量。如下:
此时就因为a同名导致直接使用a时优先选择内部类中的a,所以a和this.a都表示内部类中的a,而如果我们硬要使用外部类中的a时,就可以用 外部类的类名.this.a如OutClass.this.a表示这是外部类的a(注意这是特定的语法规则,我也不知道为什么用这样的格式能表示出外部类).
成员方法跟成员变量同理
❤️❤️而在外部类中我们不能直接访问实例内部类的成员,需要通过创建实例内部类的对象再引用访问。(这个懂得都懂,就不多讲了)
❤️❤️除此之外,到了其他类中我们用内部类对象引用就只能引用其内部方法和变量(不能引用外部类的)
用外部类对象引用也只能引用其方法和变量(不能引用内部类的)
❤️❤️下面我们再看下文案,防止你们没看懂:
![]()
静态内部类
❤️❤️我们现在说一下静态内部类跟实例内部类不同的点吧:
🎯🎯1.静态内部类可以有静态方法和变量,也可以有实例方法和变量。
🎯🎯2.静态内部类的创建不依赖于外部类的实例对象,可以直接通过外部类名创建。
如 OutClass.InnerClass innerClass = new OutClass.InnerClass();(OutClass为外部类,InnerClass为内部类)。
所以因为静态内部类的创建不需要先创建外部类,我们往往用静态内部类比实例内部类多一点。
🎯🎯3. 静态内部类可以直接访问外部类的静态成员,但不能直接访问外部类的非静态成员。如果需要访问外部类的非静态成员,可以通过在内部类中创建外部类的对象来实现。
如添加OutClass outclass=new OutClass();而后将在内部类中且原本来自外部类的实例变量和实例方法前加上outclass. 就可以了。
🎯🎯4. 如果在外部类中创建静态内部类的实例,可以省略外部类名,例如:
class OuterClass { static class InnerClass { void doSomething() { System.out.println("do something"); } } static void test1() { InnerClass inner = new InnerClass(); inner.doSomething(); } void test2() { InnerClass inner = new InnerClass(); inner.doSomething(); } }
但是在其他类中我们必须直接使用外部类名和内部类名来创建内部类的实例,否则会报错。例如:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
❤️❤️所以这就是静态内部类跟实例内部类的不同,其他的它们两基本都相同,所以我们了解了这些不同点就可以了。
局部内部类
❤️❤️定义在外部类的方法体中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。不过多了解。
所以对于局部内部类它只能在外部类的某个方法体内使用,使用性很有限。
❤️❤️【注意事项】
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用,所以我们不必过多了解
匿名内部类
🎯🎯匿名内部类是指在使用时才定义并同时实例化的内部类,没有显式的类名。其语法格式如下:
接口 类名 = new 接口() { // 匿名内部类的成员变量和方法 };
注意实施该接口的类被隐藏了,没有显示出来(以及implements也没显示出来),我们new是对隐藏的该类进行实例化。对于该种格式它是特有的,所以我们只需要记住就行。
下面直接看匿名内部类的使用:
public class Main { public static void main(String[] args) { // 创建一个接口对象,并实现其方法 MyInterface myInterface = new MyInterface() { @Override public void doSomething() { System.out.println("匿名内部类实现的方法"); } }; // 调用接口方法 myInterface.doSomething(); } } // 定义一个接口 interface MyInterface { void doSomething(); }
所以这就是匿名内部类的使用,之后当学到线程时我们会经常接触这种语法的。
总结
所以我们内部类就结束啦,内部类结束我们的类与对象才算真正的结束。之后将给大家把之前学的知识点总结起来写一个小项目。还请各位铁汁们给作者点一个小小的关注,评评论呀,感谢各位大佬~❤️❤️🥳🎉🎉🎉!
下面是一个推荐,有兴趣的大佬们可以来腾讯云入驻,超多福利方式也很简单,快来加入吧。
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=csh4tocaxqx1