内部类
分类有成员内部类,静态内部类,局部内部类,匿名内部类
概念:在一个类的内部在定义一个完整的类
特点:
-
编译后可以产生独立的字节码文件
-
内部类可以直接访问外部类的私有成员,而不破坏封装
-
可以为外部类提供必要的内部功能组件
package internalClass; //外部类 public class Outer { //内部类 public class Inner{ } } //编译后会生成 //Outer$Inner.class Outer.class 两个字节码文件
成员内部类
在类的内部定义,与实例变量,实例方法同级别的类
外部类的一个示例部分,创建内部类对象时,必须依赖外部类对象
//创建外部类对象 // Outer outer = new Outer(); // // //创建内部类的对象 // Outer.Inner inner = outer.new Inner(); //一步到位 Outer.Inner inner = new Outer().new Inner();
如果外部类和内部类出现重名的属性,优先使用访问内部类的属性
//如果内部类属性和外部类属性名字重名,优先访问内部类的,访问外部类需要下面的写法 System.out.println(Outer.this.name);
成员内部类里面不能定义静态声明
静态内部类
添加 static 关键字
不依赖外部类对象,可以直接创建或通过类名访问,可以声明静态成员
静态内部类调用外部类对象,需要创建外部类的对象,再调用
只有内部类才能是静态的,普通类不能
package internalClass.demo02; //外部类 public class Outer { private String name = "xxx"; private int age = 10; //静态内部类,和外部类同级别 static class Inner{ private String address = "uuu"; private String phone = "111"; //静态成员 private static int count = 1000; public void show(){ //调用外部类的属性 Outer outer = new Outer(); System.out.println(outer.name); System.out.println(outer.age); //调用静态内部类的属性和方法 System.out.println(address); System.out.println(phone); //调用静态内部类的静态属性 System.out.println(Inner.count); } } }
package internalClass.demo02; public class TestOuter { public static void main(String[] args) { //直接创建静态内部类方法 Outer.Inner inner = new Outer.Inner();//Outer.Inner 表示包含关系没有创建对象 inner.show(); } }
局部内部类
定义在外部类的方法中,作用范围和创建对象仅限于当前方法
静态方法里面不能直接访问非静态属性
访问局部变量 jdk1.7中有要求 变量必须是常量 jdk1.8 自动会帮你添加final:
局部内部类访问外部类当前方法中的局部变量时,因为无法保证变量的生命周期于自身相同,变量必须修饰为final
package internalClass.demo03; //外部类 public class Outer { private String name = "xxx"; private int age = 10; //因为为非静态 静态方法里面不能直接访问非静态属性 public void show(){ //定义局部变量 final String address = "yy"; //声明局部内部类 //局部内部类 不能添加 任何访问修饰符 class Inner{ private String phone = "12534"; private String email = "com"; /* 局部内部类里面不能写静态的变量 但是可以写静态常量 */ public void show2(){ //访问外部类的属性 System.out.println(name); System.out.println(Outer.this.age); //访问局部变量 jdk1.7中有要求 变量必须是常量 jdk1.8 自动会帮你添加final //原因:如果不是常量因为他只是一个局部变量会消失,而这里的方法调用了这个局部变量, // 方法和这个对象在外面被创建会一直存在,所以这个变量也需要一直存在,只能把他存入常量池,保证变量的存活 System.out.println(address+"这里实际引用的已经是常量,不是原先的变量了"); //访问内部类 System.out.println(phone); System.out.println(this.email); } } // address="l"; 这里会报错 因为address已经是常量无法被修改 //调用局部内部类 //创建局部内部类对象 这样才能使用 Inner inner = new Inner(); inner.show2(); } }
匿名内部类
没有类名的局部内部类 其他特征与局部内部类一样
必须继承一个父类或者实现一个接口
定义类,实现类,创建对象的语法合并,只能创建一个该类的对象
package internalClass.demo04; public class TestUSB { public static void main(String[] args) { //创建接口类型的变量 USB usb = new Mouse(); usb.service(); //局部内部类 // class Fan implements USB{ // @Override // public void service() { // System.out.println("失败"); // } // } //使用局部类别类创建对象 // USB usb1 = new Fan(); // usb1.service(); //匿名内部类优化 相当于创建一个局部内部类 USB usb1 = new USB() { @Override public void service() { System.out.println("失败"); } }; usb1.service(); } }