内部类
概念:在一个类的内部再定义一个完整的类
package com.object.demo01; public class Body { private String name; class Header{ //内部类也会生成一个class文件 编译之后可以生成独立的字节码文件 //内部类可为外部类提供必要的功能组件 public void show() { System.out.println(name); //内部类可以直接访问外部类的私有成员,而不破坏封装 } } }
成员内部类
package com.object.demo02; //外部类 public class Outer { //实例变量 private String name = "张三"; private int age = 18; //内部类 与实例变量、实例方法同级别的类 class Inner { private String address = "北京"; private String phone = "110"; private String name = "李四"; //private static int scores = 86; 内部类不能定义静态成员 private static final int scores = 86; //但是可以定义静态常量 //方法 public void show() { //打印外部类的属性 System.out.println(name); //内部类属性和外部类属性名字相同,优先打印内部类 System.out.println(Outer.this.name); System.out.println(age); //可以在age前加上Outer.this这样更清晰 可读性 //打印内部类的属性 System.out.println(address); //同理可以加上this. System.out.println(phone); //同理加上this. } } }
package com.object.demo02; public class TestOuter { public static void main(String[] args) { //内部类的创建必须依赖外部类对象 // //1.先创建一个外部类对象 // Outer outer = new Outer(); // //2.创建一个内部类对象 // Outer.Inner inner = outer.new Inner(); //一步到位 Outer.Inner inner = new Outer().new Inner(); inner.show(); } }
静态内部类
不依赖内部类对象,可直接创建或通过类名访问,可声明静态成员
package com.object.demo03; //外部类 public class Outer { private String name = "xxx"; private int age = 18; //静态内部类:和外部类相同 static class Inner { //只有内部类才可以用static修饰,正常的类不能用static private String address = "上海"; private String phone = "110"; //静态成员 private static int count = 10000; public void show() { //如何调用外部类的属性呢 //System.out.println(name); 不对 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 com.object.demo03; public class Test { public static void main(String[] args) { //静态内部类相当于一个外部类 //直接创建静态内部类对象 Outer.Inner inner =new Outer.Inner(); //没有new Outer(); //调用方法 inner.show(); } }
局部内部类
定义在外部类方法中,作用范围仅限于当前方法
package com.object.demo04; public class Outer { private String name = "张三"; private int age = 18; public void show() { //定义局部变量 final String address = "深圳"; //局部内部类访问外部类当前方法的局部变量时,因无法保障变量的声明周期与自身相同,变量修饰必须为final //局部内部类:注意不能加任何访问修饰符 class Inner { //在堆里 不会消失 private String phone = "110"; private String email = "111@qq.com"; // private static int count = 0; 局部内部类里不能有静态属性,同样可以有静态常量 public void show2() { //访问外部类的属性 但是show被static修饰就不能访问 //因为static 和类一起加载 外部类属性还没加载出来 System.out.println(name); //可以加上Outer.this. 可读性强 System.out.println(age); //访问内部类属性 System.out.println(phone); //可以加上this. System.out.println(email); //同上 //访问局部变量 jdk1.7要求是常量 jdk1.8自动加上final System.out.println(address); } } //创建内部类对象 Inner inner = new Inner(); inner.show2(); } }
package com.object.demo04; public class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.show(); } }
匿名内部类
-
没有类名的局部内部类
-
必须继承一个父类或者实现一个接口
-
优点:减少代码量
-
缺点:可读性较差
package com.object.demo05; //接口 public interface USB { //定义一个服务方法 void service(); }
package com.object.demo05; public class Mouse implements USB { @Override public void service() { System.out.println("连接成功,鼠标开始工作"); } }
package com.object.demo05; public class Test { public static void main(String[] args) { //创建接口类型变量 //USB usb = new Mouse(); //usb.service(); //局部内部类 class Fan implements USB { @Override public void service() { System.out.println("连接成功,风扇开始工作"); } } USB usb = new Fan(); usb.service(); } }
这是使用局部内部类。局部内部类只使用一次,可以用匿名内部类进行优化->
package com.object.demo05; public class Test { public static void main(String[] args) { //使用匿名内部类创建对象(相当于创建了一个局部内部类) // USB usb = new USB(); 报错-接口不能实例化 USB usb = new USB() { @Override public void service() { System.out.println("连接成功,风扇开始工作"); } }; usb.service(); //使用匿名内部类优化 } }