内部类相关
-
为什么:车和车的零件的变量不能放在一起;
-
什么时候:当是一部分且单独存在没意义;
-
内部类可以访问外部类的成员变量,但是外部类必须New一个对象才能访问内部类的成员变量;
理解:想象一个装修一半的车,装修了一定有车,但有车不一定装修了;
-
分类:成员,局部,静态,匿名(*重要);
接下来我们看看四种内部类:
成员内部类:
-
定义:位于和类中其他成员地位相等的位置,可以用四种权限符修饰;
-
怎么创建对象:
如果不是私有的:外部类.内部类 a = New 外部类().内部类();
如果私有:只能在外部类提供一个创建内部类的方法,调用方法(或者用多态Object);
注意:
-
jdk16以后才能在内部类中定义静态变量,但必须是final修饰,因为被static final修饰的字面量会被存放到常量池中;
-
但不能修饰静态的方法和静态的内部类,因为静态成员属于类,不需要实例化,但是内部类本身依赖外部类的实例化;
-
this关键字的使用:请大家观看内存图~
我来总结一下:
由图中我们观察到在堆内存中,内部类的对象中存有外部类的地址,所以我们要用外部类.this来使用外部类中的成员变量等;因为this存的都是内部类的地址只能找到内部类;
关于this关键字的使用:其实遵从于就近原则,如果使用this.a就是代表从内部类当中的类中找,如果是外部类.this.a就是从外部类中找,因为外部类.this代表外部类;
接下来看这个易错代码:
若这个内部类是私有的:
说明:cj()是创建私有内部类的方法:car是外部类
car a = new car();
a.cj().l();
//这样是错误的,因为编译器会检查a.cj()的返回类型,私有的话就不能对其引用和使用这个类型的对象,无法调用这个对象的方法;
//如果想调用,就直接在外部类中创建方法调用l(),因为在外部类中可以使用private的成员
静态内部类:
-
可以通过外部类.内部类.成员()调用,不需要创建对象;
OuterClass.StaticInnerClass innerObj = new OuterClass.StaticInnerClass();
-
此类中只能写外部类中静态的成员变量和方法,其他的要先创建对象;
public class Outer {
private int x = 10; // 外部类实例变量
static class SI {
public void accessOuter() {
// 错误:无法直接访问外部类的非静态成员
// System.out.println(x);
// 必须通过外部类实例访问
Outer outer = new Outer();
System.out.println(outer.x); // 正确
}
}
}
-
特殊的成员内部类;
-
允许静态变量和方法,因为不=不依赖外部类的实例化;
局部内部类:
-
定义在方法里面,地位相等于局部变量;
-
外类无法使用,在方法里new一个对象,可以访问外部类的成员;
-
四种权限修饰符只能修饰成员,不能修饰局部;
-
局部内部类可以访问方法中的局部变量,但是这些变量必须是final类型的;
-
局部内部类不能定义静态成员或方法,也不能包含静态代码块。
匿名内部类:
-
为什么:因为有时候创建只需要使用一次的类对象,可以简化代码,提高代码的可读性和可维护性。
-
怎么用:
new 类名or接口() {
// 匿名内部类的类体部分
};
-
我们来看看使用场景:
interface Interface {
public void a();
}
public class nbl {
public static void main(String[] args) {
new Interface(){
@Override
public void a() {
System.out.println("OK了");
}
}.a();
}
}
这段代码有人可能一看就蒙了,其实啊分开来看:
new Interface()代表创建一个匿名内部类的实例,所以后面才会.a()来调用;
中间才是内部类的代码;
好啦,本期内容到此结束~