1,内部类介绍
1.1什么是内部类
内部类是定义在另一个类中的类。内部类是个编译时的概念,一旦编译成功后,它就与外部类属于两个完全不同的类(当然他们之间还是有联系的)。对于一个名为OuterClass的外部类和一个名为InnerClass的内部类,在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$InnerClass.class。
1.2内部类举例
1.3内部类的作用
(1)内部类可以对除外部类的其他类隐藏
(2)内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据
(3)每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现。接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整
1.4 内部类与外部类的关系
内部类 引用 外部类
我们可以看到内部了InnerClass可以直接访问外部类OuterClass的属性,尽管它是private修饰的。
这是因为当我们在创建某个外部类的内部类对象时,此时内部类对象必定会持有一个指向那个外部类对象的引用,只要我们在访问外部类的成员时,就会用这个引用来选择外部类的成员。
外部类 引用 内部类
引用内部类我们需要指明这个对象的类型:OuterClasName.InnerClassName。同时如果我们需要创建某个内部类对象,必须要利用外部类的对象通过.new来创建内部类: OuterClass.InnerClass innerClass = outerClass.new InnerClass();
如果我们需要生成对外部类对象的引用,可以使用OuterClassName.this
2,四种内部类
2.1成员内部类
成员内部类也是最普通的内部类,它是外部类的一个成员,所以他是可以无限制的访问外部类的所有 成员属性和方法,尽管是private的,但是外部类要访问内部类的成员属性和方法则需要通过内部类实例来访问。
常见成员内部类:android消息机制new Handler()
2.2匿名内部类
(1)new 匿名内部类,这个类首先是要存在的。如果我们将那个InnerClass接口注释掉,就会出现编译出错
(2)注意getInnerClass()方法的形参,第一个形参是用final修饰的,而第二个却没有。同时我们也发现第二个形参在匿名内部类中没有使用过,所以当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。
(3) 匿名内部类是没有构造方法的
常见匿名内部类:new Thread(){ public void run(){} }.start();
2.3静态内部类
使用static修饰的内部类我们称之为静态内部类
静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外部类,但是静态内部类却没有。没有这个引用就意味着:
1、 它的创建是不需要依赖于外部类的。
2、 它不能使用任何外部类的非static成员变量和方法。
2.4局部内部类
public class test {
public void useMyInterface() {
final Integer number = 123;//java1.8后可以不加final,但是要求number值不发生变化
//number=12;让number再次赋值,则 System.out.println(number);会报错。
MyInterface myInterface = new MyInterface() {
@Override
public void doSomething() {
System.out.println(number);
}
};
myInterface.doSomething();
}
}