内部类
一、内部类的分类
- 成员内部类
- 静态内部类(static)
- 局部内部类:类在方法的内部
- 匿名内部类
二、内部类的概念(什么是内部类?)
-
在一个类的内部再定义一个完整的类
class Outer{ class Inner{ } }
三、内部类的特点
- 编译之后可生成独立的字节码文件
- 内部类可以直接访问外部类的私有成员,而不破坏封装。
四、成员内部类
-
在类的内部定义,与实例变量、实例方法同级别的类。
-
内部类是外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。(下面实例化对象的两种方式)
-
Outer out = Outer; Inner in = out.new Inner();
-
Inner inner = new Inner();
-
-
当外部类、内部类存在重名的属性时,会优先访问内部类的属性,如果要访问外部类属性可以用 外部类.this.属性 的方式访问。
-
成员内部类不能定义静态成员,但是可以定义静态常量。
五、静态内部类
-
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
//外部类 public class Outer { private String name = "xxx"; private int age = 18; //静态内部类:和外部类相同 static class Inner2{ private String address="上海"; private String phone="111"; //静态成员 private static int count = 1000; public void show() { //静态内部类show方法要怎么调用外部类的属性呢? //1先创建外部类对象 Outer outer = new Outer(); //2调用外部类对象属性 System.out.println(outer.name); System.out.println(outer.age); //调用静态内部类的属性方法 System.out.println(address); System.out.println(phone); //调用静态内部类的静态属性 System.out.println(Inner2.count); } } }
测试类:
public class Mytest { public static void main(String[] args) { //直接创建静态内部类对象 Outer.Inner2 inner = new Outer.Inner2(); //调用内部类show方法 inner.show(); } }
六、局部内部类
-
局部内部类定义在外部类的方法当中,作用范围和创建对象范围仅限于当前方法(只能在方法内使用)。
-
局部内部类访问外部类的当前方法中局部变量时,因无法保障的生命周期与自身相同,变量添加final修饰。
-
限制类的使用范围
//外部类 public class Outer2 { private String name = "刘德华"; private int age = 35; public void show() { //定义局部变量 final String address="深圳"; //局部内部类(在show方法里面的类):注意不能加任何访问修饰符 class Inner{ //局部内部类的属性 private String phone="15888888888"; private String email="[email protected]"; //在内部类再定义一个方法 public void show2() { //访问外部类的属性 System.out.println(Outer2.this.name); System.out.println(Outer2.this.age); //访问内部类的属性 System.out.println(this.phone); System.out.println(this.email); //访问局部变量,jdk1.7要求:变量必须是常量final,jdk1.8可以自动添加fianl System.out.println(address); } } //创建局部内部类对象,在用内部类对象inner调用show2方法里面的内容 Inner inner = new Inner(); inner.show2(); } }
测试类:
public class Mytest1 { public static void main(String[] args) { Outer2 out = new Outer2(); out.show(); } }
七、匿名内部类
-
没有类名的内部类(一切特征都与局部内部类相同)
-
必须继承一个父类或者一个接口
-
定义类、实现类、创建对象的的语法合并,只能创建一个该类的对象。
-
优点:减少代码量
-
缺点:可读性较差
接口类:
//接口 public interface Usb { //服务方法 void service(); }
鼠标类:
public class Mouse implements Usb{ @Override public void service() { // TODO Auto-generated method stub System.out.println("连接成功,鼠标开始工作!"); } }
测试类:
public class Mytest2 { public static void main(String[] args) { /* //创建接口变量 Usb usb = new Mouse(); usb.service(); //局部内部类 class Fan implements Usb{ @Override public void service() { // TODO Auto-generated method stub System.out.println("连接电脑成功,风扇开始工作了!"); } } //使用局部内部类创建对象 Usb usb2 = new Fan(); usb2.service(); */ //以上的类只使用一次,所以没必要单独定义一个类,这时候就可以使用内部类 //使用匿名内部类优化(相当于创建一个局部内部类),只用一次之后,后面就不再用了 Usb usb3 = new Usb(){ @Override public void service() { // TODO Auto-generated method stub System.out.println("连接电脑成功,风扇开始工作了!"); } }; usb3.service(); } }