1.内部类的分类
- 成员内部类(在类的成员位置)
- 局部内部类(在类的局部位置,方法里面,用的不多)
- 匿名内部类(是局部内部类的一种特殊形式)
2.成员内部类的访问特点
1. 成员内部类可以直接访问外部类的成员(包括私有成员)
2. 外部类或者其他类要访问内部类的成员,必须先创建内部类的对象
3. 如果内部类和外部类有同名的成员,此时内部类中的 方法想要访问该成员,则默认访问的是 内部类本身的成员,如果要访问外部类的成员,可以使用外部类名.this.成员来访问外部类成员
package myInnerClass;
public class Outer {
private int num=10;
public class Inner{
private int num=20;
public void f(){
System.out.println(num); //默认访问的是内部类的num = 20
System.out.println(Outer.this.num); //通过外部类名.this.成员访问外部类的同名成员,也说明能访问外部类的私有成员
}
}
}
测试类:
package myInnerClass;
public class Test {
public static void main(String[] args) {
Outer.Inner inner=new Outer().new Inner();//通过外部类对象访问到内部类构造方法,然后实例化。
inner.f(); //使用内部类的成员必须先创建内部类对象
}
}
3.创建成员内部类对象的方法
1.在外部类中创建内部类对象
//此方法为外部类中的方法
public Inner getInstance(){
Inner inner = new Inner(); //外部类中创建内部类对象,和其他创建对象的方式相同
return inner;
}
2.在其他类中创建内部类对象
//这是一个测试类
public class Test {
public static void main(String[] args) {
Outer.Inner inner=new Outer().new Inner(); //其他类中创建内部类的方式,需要借助外部类对象
inner.f();
}
}
4.静态成员内部类
访问外部类中的数据:
静态内部类中所有方法都只能访问外部类中的静态成员且是通过外部类名直接访问外部类的静态成员,
访问内部类中的数据:(这点和外部类一样)
其中非静态方法可以访问内部类的所有成员,静态方法只能访问内部类中的静态成员。
非静态内部类中不能有静态成员
public class Outer {
private static int num=10;
private int age=30;
public static class Inner{
private int num=20;
private static int age=40;
public void f1() { //非静态方法
System.out.println(num); //访问静态内部类的非静态成员
System.out.println(age); //访问静态内部类的静态成员
//System.out.println(Outer.this.age);//报错,静态内部类的非静态方法也只能访问外部类的静态成员
System.out.println(Outer.num); //直接通过外部类名 访问外部类的静态成员
}
public static void f2(){ //静态方法
//System.out.println(num); //报错,不能访问静态内部类的非静态成员
System.out.println(age);//只能访问静态内部类的静态成员
//System.out.println(Outer.this.age); //报错
System.out.println(Outer.num); //只能访问外部类的静态成员
}
}
}
2.其他类创建静态内部类对象
package myInnerClass;
public class Test {
public static void main(String[] args) {
Outer.Inner inner=new Outer.Inner(); //其他类创建静态类部类,不需要创建外部类对象
inner.f1(); //访问内部类中的非静态方法需要创建内部类对象
Outer.Inner.f2(); //访问内部类中的静态方法直接使用类名
}
}
5.内部类的访问修饰符
内部类可以使用public default protected private 4种修饰符修饰(和外部类相比多了一种private)
如:使用private 修饰,则只能在外部类和内部类里面创建内部 类对象,其他类里面不能创建。
6.匿名内部类
当我们需要使用一个子类去重写某个父类的方法且这个类只是临时使用时,可以写一个匿名的内部类,该类没有类名,且是父类的子类或者接口的实现类。
//可以是普通类,抽象类,或者接口
public class Father {
public void show(){
System.out.println("father show");
}
}
public class Test01 {
public static void main(String[] args) {
Father son = new Father() {
@Override
public void show() {
System.out.println("son show");
}
};
son.show();
}
}