什么是内部类
把类定义在其他类的内部,这个类就被称为内部类。
内部类的分类
内部类分为两种,分别为成员内部类和局部内部类:
- 成员内部类:和成员变量和成员方法定义在同级
- 局部内部类:和局部变量定义在同级,包括在构造方法,成员方法体和静态方法体中
class Outer { class InnerA {//成员内部类 } { class InnerB {//局部内部类 } } static { class InnerC {//局部内部类 } } public Outer() { class InnerD { //局部内部类 } } public void show() { class InnerE {//成员内部类 } } }
成员内部类访问特点
- 内部类可以直接访问外部类的全部成员。
- 外部类要访问内部类的成员,必须创建对象。
- 成员内部类一般多用private修饰和static修饰
class Outer { private int age = 20; class Inner { public void getAge() { System.out.println(age); } } public void method() { //找不到符号 //getAge(); Inner inner = new Inner(); inner.getAge();
}
}
public class Test { public static void main(String[] args) { Outer.Inner inner = new Outer().new Inner(); inner.getAge(); } }
上面的例子中,可以直接通过new Outer(). new Inner();来访问内部来,这种访问一般不安全,因为类之所以定义在内部而不定义在外部,肯定有安全性需求,这时候可以在内部类前的修饰符加private,如果类中的成员变量,外部只能通过指定的方法来访问,这个时候在对外的方法可以提供验证,例如:
class Outer { private class InnerA { public void play() { System.out.println("play"); } } public void getInner(String name) { if(name.equals("lili")){ new InnerA().play(); } } } public class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.getInner("lili"); } }
当然,成员内部类也常用static修饰,这样访问起来便利性比较高,但是静态内部类只能访问静态外部成员变量。
public class Test { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); inner.getAge(); } } class Outer { private static int age = 20; static class Inner { public void getAge() { System.out.println(age); } } public void method() { Inner inner = new Inner(); inner.getAge(); } }
局部内部类访问特点
- 可以直接访问外部类的全部成员
- 在局部位置,可以创建内部类对象来使用局部内部类提供的功能
- 局部内部类访问局部变量必须用final修饰
class Outer { private String name = "lili"; public void show(){ int phoneNum = 10086; class Inner { final int age = 20; public void getAge() { // phoneNum = 110;//Error:(13, 17) java: 从内部类引用的本地变量必须是最终变量或实际上的最终变量 int miniPhoneNum = phoneNum;//可以访问 System.out.println(age); System.out.println(phoneNum); System.out.println(name); } } new Inner().getAge(); } } public class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.show(); } }
为什么局部内部类只能访问final类型的局部变量?
局部变量是随着方法的调用而调用,随着调用完毕而消失。而堆内存的内容并不会立即消失。所以,我们加final修饰。加入final修饰后,这个变量就成了常量。既然是常量。你消失了,我在内存中存储的是数据20,所以,我还是有数据在使用。
内部类中如何区分多层同名变量
class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; System.out.println(num); System.out.println(this.num); //System.out.println(new Outer().num); System.out.println(Outer.this.num); } } }