内部类
内部类(类里嵌套类)Inner Class
public class A{
class B{}
}
内部类不是在一个java源文件中编写俩个平行的俩个类,而是在一个类的内部再定义另外一个类。我们可以把外边的类称为外部类,在其内部编写的类称为内部类。
内部类分为四种,成员内部类、静态内部类、局部内部类、匿名内部类
1、成员内部类(实例内部类、非静态内部类)
1)类似于外部类一个属性
2)可以访问外部类的所有东西
3)成员内部类中不能写静态属性和方法
4)成员内部类访问外部类的非静态属性方法:
外部类名.this.属性/方法名,访问外部类的静态属性方法,直接类名.属性/方法名
5)外部类访问成员内部类:
外部类.内部类 引用 =(new 外部类()).new 内部类();//不导包,先创建外部类对象,再创建内部类对象,就像访问属性;然后用引用进行操作
例如:
public class InstanceOutterClass{
private String name;
private static int age;
public void say(){}
public static void go(){}
public class InstanceInnerClass{
InstanceOutterClass.this.name="zs";
InstanceOutterClass.this.say();//内部类访问外部类的非静态的属性或方法
InstanceOutterClass.age=20;
InstanceOutterClass.go();//内部类访问外部类的静态的属性或方法
public void walk(){}//内部类自己的方法
}
}
main:
InstanceOutterClass.InstanceInnerClass out_in=(new InstanceOutterClass() ).new InstanceInnerClass();
out_in.walk();//外部类调用内部类的方法
2、静态内部类
1)静态内部类中可以写静态属性和方法
2)静态类不能访问非静态的属性方法,所以内部类只能访问外部类的静态属性方法;采用:外部类类名.属性/方法名
3)内部类访问自己的属性方法,采用:this.属性/方法名
4)外部类的访问内部类的静态属性方法,直接用内部类名.属性/方法名;访问内部非静态属性方法,要new一个内部类的对象再访问。
外部类.内部类 a=new 外部类.内部类();可以使用引用a访问内部类的属性和方法
public class StaticOutterClass{
private String name;
private static int num;
public void say(){}
public static void go(){}
public static class StaticInnerClass{
}
}
main:
//这里理解可以把静态内部类看做是外部类的静态属性,直接使用外部类名进行调用
StaticOutterClass.StaticInnerClass out_in=new StaticOutterClass.StaticInnerClass();
3、局部内部类
1)局部内部类是在一个方法内部声明的一个类
2)局部内部类中可以访问外部类的成员变量及方法
3)局部内部类中如果要访问该内部类所在方法中的局部变量,那么这个局部变量就必须是final修饰的
4)局部内部类,不能public static private修饰,类似于局部变量;
5)局部内部的访问外部类 外部类名.this.属性/方法名 ;内部类访问自己的属性方法 内部类名.this.属性方法(this可省)
例如:
public class LocalOutterClass{
private String name;
private static int age;
public void say(){}
public static void go(){}
public void test(final int j){
final int i = 10;
class LocalInnerClass{//局部内部类
private String name;
private int age;
public void say(){
System.out.println(name);
System.out.println(this.name);
System.out.println(LocalInnerClass.this.name);
System.out.println(LocalOutterClass.this.name);
System.out.println(LocalOutterClass.age);
LocalOutterClass.this.say();
LocalOutterClass.go();
System.out.println(i);
System.out.println(j);
}
}
LocalInnerClass lic = new LocalInnerClass();
lic.say();
}
}
4、匿名内部
1)没有名字的内部类,不用class,没有extends和implements
2)有构造器,但是不能写也用不了,可以通过javap(反编译)看到
3、直接写{},但是必须依附在别的类或接口上
如果依托的是类,那么创建出来的匿名内部类就默认是这个类的子类
如果依托的是接口,那么创建出来的匿名内部类就默认是这个接口的实现类。
new person(){
//可实现类中抽象方法,或重写普通方法;一般不会写自己独有的方法
};
//寄生在person类
//声明的同时就得创建对象;只能使用一次,没有名字;只有大括号,只不过这个大括号依附在类或接口上
//依附在类上,表示这个匿名内部类是该依附类子类
//依附在接口上,表示这个匿名内部类是该接口的实现
接口 接口名 a=new 接口名(){
//匿名内部类实现所依附接口的方法
};
//接口不能new对象,这里是new出一个接口的匿名内部类,在匿名内部类里写接口实现。
例如:
public interface Work{
void doWork();
}
public class AnonymousOutterClass{
private String name;
private static int age;
public void say(){}
public static void go(){}
public void test(){
final int i = 90;
Work w = new Work(){//匿名内部类
public void doWork(){
System.out.println(AnonymousOutterClass.this.name);
System.out.println(AnonymousOutterClass.age);
AnonymousOutterClass.this.say();
AnonymousOutterClass.go();
System.out.println(i);
}
};
w.doWork();
}
}