内部类
1.内部类
* 在类的内部也可以定义另一个类。如果在类Outer的内部再定义一个类Inner,此时Inner就称为内部类,而Outer则称为外部类。
* 内部类跟方法一样,可以使用全部的访问权限修饰符,用法是一样的
* 当内部类声明成public或private等时,对其访问的限制与成员变量和成员方法完全相同。
* 内部类和外部类之间存在逻辑上的所属关系
* Inner class 一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
* Inner class 的名字不能与包含它的类名相同
* Inner class 可以使用包含它的类的静态和实例成员变量,也可以使用它所在方法的局部变量
内部类减少了类文件编译后的产生的字节码文件的大小但使程序结构不清晰
内部类的最大优点:可以方便的访问外部类的私有属性
* 内部类跟普通类是一样的,普通的类能干什么,内部也可以干什么 比如:继承 实现接口 可以帮助外部类实现多继承的功能
2.成员内部类
* 成员内部类;跟成员属性(方法同级),可以类比成员属性
class Inner{
}
protected class Inner2{
}
public class Inner3{
}
private class Inner4{
}
* 成员内部类也叫实例内部类
* 成员内部类中不能定义static变量
* 成员内部类持有外部类的引用
* 在文件管理方面,成员内嵌类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内嵌类名称.class”
* 外部实例化类的格式:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
>类比
Outer.Inner2 inner2 = new Outer().new Inner2();
* 成员内部类运用场景:
* 通过内部类可以实现类的多继承
* 如果外部类,是一个逻辑非常复杂了的一个,需要操作好多属性 或方法.这个时候,可以功能进行拆分让某个或多个内部类,帮忙处理
* 因为访问成员内部类中属性,需要通过外部类的对象,进行内部类对象的创建,然后通过内部类的对象进行访问。如果,在内部中声明静态属性,那么只能同内部类的类名进行访问,此时,如果内部类是成员内部类时,那么外部类不能通过外部类名.内部类名访问 内部类静态成员属性,所以:要么把内部类变成静态内部类,要把静态成员属性变成常量(常量表达式)
* 外部类访问控制
public void method2(){
//成员内部类可以访问外部类的私有属性
System.out.println("outer 私有的属性:" + privateField);
//成员内部类可以访问外部类的静态属性
System.out.println("outer 静态的属性:" + staticField);
}
3.静态内部类
* 静态内部类 可以类比,静态属性
* 如果一个内部类使用static声明,则此内部类就称为静态内部类,其实也相当于外部类。可以通过外部类.内部类来访问。
* 静态内部类不会持有外部类的引用,创建时可以不用创建外部类
* 静态内部类可以访问外部的静态变量,如果访问外部类的成员变量必须通过外部类的实例访问
* 外部实例化类的格式:
Outer.Inner inner = new Outer.Inner();
* 非静态方法,可以访问内部中静态/非静态成员,可以访问外部类的静态成员,无法访问,外部类非静态成员
【原因】:
StaticOuter.Inner inner = new StaticOuter.Inner();
创建静态内部类对象时候,没有创建外部的对象,此时,不是通过外部类对象访问非静态属性,所以不能访问(如果想调用外部类的非静态属性,必须要有外部类的对象,应该实例化一个外部类的对象,比如Outer outer = new Outer();)
* 静态方法只能访问静态属性或方法,不能访问非静态方法或/属性,不管是外部还是内类
4.局域内部类
* 无法通过普通new进行创建,可以通过继承/实现接口的方式进行
* 局部内部类也叫区域内嵌类
* 局部内部类与成员内部类类似,不过,区域内嵌类是定义在一个方法中的内嵌类,所以类的作用范围仅限于该方法中,而类生成的对象也只能在该方法中使用。另外,由于是在方法中定义,因此区域内嵌类不能加上private,protected,public中的任何一个修饰符
* 不能包含静态成员
* 使用局部内部类时,传入的参数,如果在内部中使用时,需要使用final进行修饰
5.匿名内部类
InterInner aaa = new InterInner() {
@Override
public void method() {
}
};
* 如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类
* 匿名内部类,在任何地方都是创建,只要能定义引用类型的变量的地方就行
* 特点:
* 没有具体的类名,每使用一次,相当于创建一个类
* 必须继承某个类或者实现某一接口
* 没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适
* 匿名类内部不用声明类名称,而是用new直接产生一个对象。匿名内部类是在抽象类和接口的基础上发展起来的。它可以是继承某个类,或是实现某个接口。
比如:可以直接继承Object类定义一个匿名类,在重写toString方法后,用匿名类直接产生一个对象。
* 在文件管理方面,内嵌匿名类编译后生成的.class文件的命名方式是”外部类名称$编号.class”,编号为1,2,3…n,编号为x的文件对应的就是第x个匿名类