内部类
内部类的作用
每个内部类都能独立地继承来自一个(接口的)实现,所以无论外部类是否继承了某个(接口的)实现,对于内部类都没有影响,如果没有内部类提供的可以继承多个具体或抽象的类的能力,一些设计与编程问题就很难解决,从这个角度看,内部类使得多重继承的解决方案变得完整,接口解决了部分问题,而内部类有效的实现了"多重继承"
成员
成员内部类,静态内部类
局部
方法内部类、匿名内部类
依赖外部类对象的, 成员内部类,方法内部列,匿名内部类
静态内部类不依赖外部类的对象,所以,我们在项目中优先考虑选择静态内部类(不会产生内存泄漏)
问题: 局部内部类访问局部变量必须用final修饰,为什么?
当调用这个方法时,局部变量如果没有用final修饰,它的生命周期和方法的生命周期是一样的,当方法被调用时会入栈,方法结束后即弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,显然已经无法使用了,如果用final修饰会在类加载的时候进入常量池,即方法弹栈,常量池的常量还在,也就可以继续使用了。(在jdk1.8中取消了这个特性)
关于内部类的代码整理:
package com.lili.innerClass; /** * 内部类: * 1.成员内部类:直接定义在方法内部的类 * 2.方法内部类:在一个类的方法中定义一个类 * (1)方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化 * (2)方法内部类对象不能使用该内部类所在方法的非final局部变量 * 3.静态内部类:在一个类内部定义一个静态内部类 * (1)静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它,静态嵌套类仅能访问外部类的静态成员方法 * 4.匿名内部类就是没有名字的内部类 * 匿名内部类的三种情况: * (1) 继承式的匿名内部类 * (2) 接口式的匿名内部类 * (3) 参数式的匿名内部列 * * @author: QiJingJing * @create: 2021/7/4 */ public class Test1 { public static void main(String[] args) { Outer outer = new Outer(); // Outer.Inner inner = outer.new Inner(); // inner.show(); 影响美观,不建议使用 outer.innerShow(); outer.showClass(); Outer.Inner2 inner2 = new Outer.Inner2(); inner2.show(); // 抽象类式 outer.print1(); // 接口式 outer.print2(); // 参数式 outer.print3(() -> System.out.println("我是参数式匿名内部类")); } } class Outer { private String name; // 建议在外部类中定义一个方法,对外提供访问内部类的接口 public void innerShow() { Inner inner = new Inner(); inner.show(); } // 成员内部类 private class Inner { public void show() { System.out.println("我是成员内部类"); } } // -------------方法内部类--------- // show方法的参数或局部变量,实际必须是常量final public void showClass() { int x = 10; // 在一个方法中定义一个类 class Inner1 { public void show() { // x++; 从内部类引用的本地变量必须是最终变量或实际上的最终变量 System.out.println("我是方法内部类" + x); } } Inner1 inner1 = new Inner1(); inner1.show(); } // -----------静态内部类--------- static class Inner2 { public void show() { System.out.println("我是静态内部类"); } } // ------------匿名内部类------- // 抽象式匿名内部类 public void print1() { new Dog() { @Override void run() { System.out.println("小狗会跑"); } }.run(); } // 接口式匿名内部类 public void print2() { new Person() { @Override public void eat() { System.out.println("人会吃"); } }.eat(); } // 参数式匿名内部类 public void print3(Person person) { person.eat(); } } /** * 定义一个抽象类 */ abstract class Dog { abstract void run(); } /** * 定义一个接口 */ interface Person { void eat(); }