据说这是自学Java的一大关卡,比较难理解。
什么叫内部类呢?
顾名思义,在类的里面还有一个类。
其中在里面的那个类就是内部类,在外面的那个类就是外部类。
我们知道一个类,有成员变量和成员方法。
若是内部类在成员变量处,那它就是成员内部类;
若是内部类在成员方法内,那它就是局部内部类。
代码如下:
①内部类可以直接访问外部类的成员变量,包括私有成员变量。
格式为:外部类名.this.外部类成员变量(注意是外部类类名+this)。
②内部类访问本类的成员变量。
格式为:this.内部类成员变量。
不管是内部类还是外部类,其成员的访问都是基于对象访问的。
内部类对象的创建有两种格式:
先创建外部类对象,再创建内部类对象。
注意:内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。比如:OuterClass$InterClass.class
内部类也可以定义在成员方法中,这种情况叫局部内部类。
内部类只能在方法中或者某个作用域内访问。
其他类是无法访问局部内部类的。
成员内部类,在其他类中是可以访问的,上面也说了两种创建对象的格式,但是在局部内部类中是不可以的。
①直接变量名是指内部类局部变量;
②this.变量名是指内部类成员变量;
③外部类名.this.变量名是指外部类成员变量
④访问外部类局部变量,其变量得是final类型,不然会报错。
思考有两个问题:
1.如果外部类局部变量和内部类局部变量重名,如何访问外部类局部变量?
这个问题困扰了我蛮久的,我在网上查询了很久,最终得出的结论是:如果重名,没法访问外部类局部变量,因为就近原则,外部类局部变量会被内部类局部变量覆盖掉。
2.为什么外部类局部变量得是final类型?
在成员内部类中就说过,虽然内部类是在外部类里面,但是外部类和内部类是会生成两个class文件的,也就是说它们是各自存储各自的数据。
如果不是final类型,会出现外部类局部变量改变了,但是内部类存储的还是以前的那个数据的情况。
除了成员内部类、局部内部类,还有一个匿名内部类。
什么叫匿名内部类呢?
按照字面意思的理解,就是没有名称的内部类。
现在有一个需求,控制台输出每个人在唱什么歌。
最常规简单的方法如何做?看如下代码:
①创建一个Sing接口;
②定义一个抽象方法sing();
③创建一个类People实现Sing接口;
④重写方法Sing();
⑤在测试类中创建People对象;
⑥用对象调用方法sing()。
打印出来结果就是:刘小爱在唱《七里香》。
那么问题来了,如果这个对象只需要使用一次,创建了一个子类People,结果只使用了一次,这个过程又这么的繁琐。
有没有更简便的方法呢?
这就需要匿名内部类了。代码如下:
不需要创建一个People类,然后实现接口,最后建立对象,调用方法。
①匿名内部类就相当于,在常规方法中的People对象,但是因为使用匿名内部类的话不需要建立子类,故没有子类名,便直接用父接口命名代替,这也是格式:new Sing(){}的由来。
②调用自己重写后的方法。
匿名内部类在父类是抽象类的时候也可以使用,和接口时的格式是一样的。