17.内部类
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
18.内部类的位置
1.内部类定义在成员位置上
可以被private static成员修饰符修饰。
被static修饰的内部类只能访问外部类中的静态成员。
2.内部类定义在局部位置上
也可以直接访问外部类中的成员。
同时可以访问所在局部中的局部变量,但必须是被final修饰的。
19.匿名内部类
就是内部类的简化写法。
前提:
内部类可以继承或实现一个外部类或者接口。
格式为:
new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}
简单理解:
就是建立一个带内容的外部类或者接口的子类匿名对象。
class Outer{ private int num = 3; static int num2 = 7; //内部类:定义在成员位置上,它就相当于外部类的成员一样,可以被成员修饰符所修饰。 public class Inner{ void show(){ System.out.println("show num="+num); } } void method(){ //外部类要访问内部类中的成员,必须要创建内部类中的对象 Inner in = new Inner(); in.show(); } static class Inner2{//被static修饰的内部类只能访问外部类中的静态成员 void show2(){ System.out.println("show2 num2="+num2); } } static class Inner3 { //当内部类中定义了静态成员,该内部类必须被静态修饰 static void show3(){ System.out.println("show3 num2="+num2); } } } class InnerDemo{ public static void main(String[] args) { /* 直接访问内部类成员的方式。 */ //1,对非静态的内部类中的非静态成员访问。 Outer.Inner in = new Outer().new Inner(); in.show(); //2,访问静态内部类中的非静态成员。 Outer.Inner2 in = new Outer.Inner2(); in.show2(); //3,访问静态内部类中的静态成员。 Outer.Inner3.show3(); //外部类访问外部类的方法,该方法中有内部类对象访问的方法 Outer out = new Outer(); out.method(); }}
内部类直接访问外部类成员的原因
非静态的内部类之所以能直接访问外部类成员的原因是:它持有了一个外部类对象的引用。
class Outer{ private int num = 2; class Inner{ private int num = 3; void show(){ int num = 4; System.out.println("num="+num); //结果是4 System.out.println("num="+this.num); //结果是3 System.out.println("num="+Outer.this.num); //结果是2 } } void method(){ new Inner().show(); }}
内部类在局部访问的原因
class Outer{ private int num = 3; void method(){ final int x = 7; //内部类定义在局部中,只能访问被final修饰的局部变量。 //不被final修饰的局部变量生命周期随着方法的释放而释放。 class Inner{//定义在局部的内部类。 void show(){ System.out.println("x="+x); //System.out.println("num="+num); } } new Inner().show(); }} class Outer2{ private int num = 4; Object obj ; public void method(){ final int x = 4; class Inner{ public String toString(){ return "hahah"+x; } } this.obj = new Inner(); }}
class InnerDemo3 { public static void main(String[] args) { //new Outer().method(); Outer2 out = new Outer2(); out.method(); System.out.println(out.obj.toString()); }}
/*匿名内部类的形式。其实就是对内部类进行简化书写。必须有前提:内部类必须继承或者实现类或接口。 格式:new 父类名或者接口名(){定义内部类的内容;} 匿名内部类其实就是一个子类匿名对象。 */ abstract class AbsDemo{ abstract void function();} class Outer{ int num = 4; /* class Inner extends AbsDemo{ void function(){ System.out.println("num="+num); } } */ void method(){ //new Inner().function(); new AbsDemo() { //创建了子类的对象并且调用了子类的方法。 //对内部类的描述。 void function(){ System.out.println("num===="+num); } }.function(); //枚红色的部分是绿色部分的简写, new X(){}是创建X子类对象 }} class NoNameInnerDemo {public static void main(String[] args) { Outer out = new Outer(); out.method(); }}