内部类
语法:
class Outer{//外部类
class Inner{//内部类
}
}
class Other{外部其他类
}
类中的五大成员:
属性、方法、构造器、代码块、内部类
内部类的分类(四种):
a. 定义在外部类局部位置上(如在大括号里{},像方法、代码块)
1. 局部内部类(有类名)
2. 匿名内部类(没有类名)
b. 定义在外部类的成员位置上(和属性、方法等位置相同)
1. 成员内部类(没有static修饰)
2. 静态内部类(有static修饰)
局部内部类:
public class LocalInnerClass{//5. 其他外部类不能访问局部内部类,即不能在这里实例化局部内部类对象 public static void main(String[] args){ Outer outer = new Outer(); outer.m1();//调用m1方法,会实例化局部内部类inner,然后会调用f1方法 } } class Outer{//外部类 private int n1 = 10; public void m2(){ System.out.println("Outer m2()..."); } public void m1(){ private int n1 = 80; //2. 局部内部类不能添加访问修饰符,但可以用final修饰,添加后就不能被其他内部类继承了 //3. 作用域:局部内部类仅仅在定义它的方法或代码块中,在其他地方就使用不了 class Inner{//局部内部类(本质还是一个类) public void f1(){ System.out.println("n1="+n1 + "我i部内的n1="+Outer.this.n1);//1. 可以直接访问外部类的所有成员,包括私有的 //6. 如果外部类和局部内部类的成员重名时,默认遵循就近原则, //如果要想使用外部类的成员,可以用 外部类.this.成员 来访问 m2(); } } //4. 外部类怎么访问局部内部类?在外部类的方法中,可以创建Inner对象,然后再调用内部类的方法 Inner inner = new Inner(); inner.f1(); } }
匿名内部类:
1. 本质还是一个类
· 2. 定义在外部类的局部位置(方法或代码块中)
3. 该类没有名字(其实底层给其分配了一个名字)
4. 是一个对象
语法:new 类或接口(参数列表){//这里有一个大括号,就表示定义一个匿名内部类
类体;
}
为什么要用匿名内部类?
比如我们想要使用某个接口,不用匿名内部类的话,就只能再定义一个类去implement这个接口,然后再重写接口中的抽象方法,这样我们就可以new一个对象来调用接口里的方法了。然而在程序中,我们只要用实现接口的那个类一次,这样定义的这个类就会显得很冗余---》所以就要引入匿名内部类来解决这个问题
public class AnonymityInnerClass{//其他外部类 public static void main(String[] args){ Outer outer = new Outer(); outer.method();//输出cring... 和testing... } } class Outer{//外部类 private int n1 = 10; public void method(){ //基于接口的匿名内部类 //a的编译类型:A //a的运行类型:匿名内部类Outer$1 向上转型 //2. 这里的new是jdk底层在创建匿名内部类Outer$1时,立即马上就创建了Outer$1实例,并把地址返回给a //3. 匿名内部类使用一次就不能再使用,但对象a可以在生命周期内重复使用 A a = new A(){//1. 这里就是一个匿名内部类,定义在外部类的方法中 A a = new A(){}等价于 class Outer$1 implements A{//内部类的真实定义,Outer$01有系统分配 public void cry(){ // public void cry(){ System.out.println("cring..."); // System.out.println("cring..."); } // } }; //} // A a = new Outer$01(); a.cry(); //基于类的匿名内部类 //father的变异类型:Father //fathre的运行类型:匿名内部类Outer$2 ;相当于向上转型 /*等价于 class Outer$2 extend Father(){ public void test(){//重写了Father的方法 System.out.println("testing..."); } }*/ //("zhangsan")会传递给Father的构造器 Father father = new Father("zhangsan"){//这里有大括号,就是匿名内部类; public void test(){//重写了Father的方法 System.out.println("testing..."); } }; father.test() } } interface A{//接口 public void cry(); } class Father{//类 public Father(String name){//构造器 System.out.println("Father 构造器..."); } public void test(){//方法 System.out.println("Father testing...");
} }