Java--内部类
一、内部类的分类
成员内部类 静态内部类 局部内部类 匿名内部类
- 概念:在一个类的内部再定义一个完整的类。
- 特点:
- 编译之后可生成独立的字节码文件。
- 内部类可直接访问外部类的私有成员,而不破坏封装
- 可为外部类提供必要的内部组件
package com.monv.neibulei; public class Body { private String name; class Head{ public void show(){ System.out.println(name); //可以直接访问外部类的私有成员 } } }
二、成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类。
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
- 当外部类、内部类存在重名属性时,会优先访问内部类属性。(访问外部类属性时需要加 外部类名.this.属性)
- 成员内部类不能定义静态成员。但是可以定义静态常量。
package com.monv.neibulei; //外部类 public class Outer { //实例变量 private String name = "小明"; private int age = 20; //内部类 class Inner{ //不能包含静态成员 但是可以包含静态常量 // private static String S1="aaa";//这句是不可以的 // private final static String S1="aaa";//这句是可以的(静态常量) private String name = "小红"; private String address = "北京"; private String phone = "15930221236"; //方法 public void show(){ //打印外部类属性 内部类属性和外部类属性重名的时候 访问外部类属性需要加Outer.this. System.out.println(Outer.this.name); System.out.println(Outer.this.age); //打印内部类属性 System.out.println(this.address); System.out.println(this.phone); } } } ---------------------测试------------------------------- package com.monv.neibulei; import com.monv.neibulei.Outer.Inner; public class TestOuter { public static void main(String[] args) { // //1、创建外部类对象 // Outer outer = new Outer(); // //2、创建内部类对象 // Inner inner = outer.new Inner(); //一步到位的写法 Inner inner = new Outer().new Inner(); inner.show(); } }
三、静态内部类(相当于外部类,普通的外部类包含什么,静态内部类就包含什么)
- 不依赖外部类对象,可以直接创建或通过类名访问,可声明静态成员。
- 只能直接访问外部类的静态成员(实例成员,需要实例化外部类对象)
package com.monv.neibulei_2; //外部类 注意:普通的类不能用static修饰,只有内部类才可以用static修饰 public class Outer { private String name = "小明"; private int age = 20; //静态内部类(在成员内部类的基础上增加 static关键字修饰) 级别和外部类相同 static class Inner{ private String address="河北"; private String phone = "123"; //静态成员 private static int count = 1000; //方法 public void show(){ //调用外部类属性 //1.先创建外部类对象 Outer outer = new Outer(); //2.调用外部类对象属性 System.out.println(outer.name); System.out.println(outer.age); //调用静态内部类的属性和方法 System.out.println(address); System.err.println(phone); //调用静态内部类的静态属性(静态属性访问:类名.静态属性) System.out.println(Inner.count); } } } ----------------------------测试--------------------------------- package com.monv.neibulei_2; public class TestOuter { public static void main(String[] args) { //直接创建静态内部类对象 注意 这里new的时候Outer后没有() Outer.Inner inner = new Outer.Inner(); //调用方法 inner.show(); } } ----------------------------------------------------------------
四、局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须用final修饰
- 限制类的使用范围(只能在当前的方法中使用)
package com.monv.neibulei_3; import java.util.concurrent.CountDownLatch; //外部类 public class Outer { private String name = "小明"; private int age = 20; public void show(){ //定义局部变量 用final修饰表示常量 说明值不可以被修改 final String address ="河北"; //局部内部类 注意:不能带任何访问修饰符 class Inner{ //局部内部类的属性 private String phone = "1236523"; //不能包括静态变量 可以包括静态常量 // private static int count = 2000;//这个是不可以的 // private final static int count = 2000; //这个是可以的(静态常量) //局部内部类的方法 public void show2(){ //访问外部类的属性(直接访问) System.out.println(Outer.this.name); System.out.println(Outer.this.age); //访问内部类的属性 System.out.println(this.phone); //访问局部变量:jdk1.7 要求变量是常量 final;jdk1.8自动添加final System.out.println(address); } } //创建内部类对象 Inner inner = new Inner(); inner.show2(); } } -------------------------------------------------- package com.monv.neibulei_3; public class TestOuter { public static void main(String[] args) { //这里只能创建外部类对象 用外部类对象调用show方法 //show方法中有局部内部类 如果想要调用局部内部类的show2方法 则需要在show方法中定义 局部内部类对象 然后再调用show2方法 Outer outer = new Outer(); outer.show(); } } ---------------------------------------------------
五、匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)
- 必须继承一个父类或者实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
- 优点:减少代码量
- 缺点:可读性较差
例如:之前写的Usb的接口,需要定义一个实现类 Mouse类来实现这个接口,然后再定义一个Usb的变量,实例化成Mouse对象之后再调用方法。现在可以用匿名类来进行优化。
---------------------接口----------------------------- package com.monv.neibulei; //接口 public interface Usb { void service(); } ---------------------鼠标的实现类--------------------- package com.monv.neibulei; public class Mouse implements Usb { @Override public void service() { System.out.println("鼠标连接成功,开始工作。。"); } } ------------------------测试----------------------------- package com.monv.neibulei; public class TestUsb { public static void main(String[] args) { //方法1.创建接口类型的变量 Usb usb = new Mouse(); usb.service(); //方法2.定义局部内部类 // class Upan implements Usb{ // // @Override // public void service() { // System.out.println("U盘连接成功,开始工作"); // } // // } // //使用局部内部类创建对象 // Usb usb2 = new Upan(); // usb2.service(); //方法3.使用匿名类优化(相当于创建了一个局部内部类) Usb usb2 = new Usb() { @Override public void service() { System.out.println("U盘连接成功,开始工作。。"); } }; usb2.service(); } } -----------------------------------------------------------------------
输出是最好的输入。把学习的内容输出出来,加深记忆;