内部类的几种使用情况(比较匿名内部类与Lambda表达式)
A:内部类概述:
把类定义在另一个类(外部类)内部,此类为内部类。
B:内部类访问特点
a:内部类可以直接访问外部类的成员,包括私有。(相当于外部类的成员,如成员方法可以成员属性,内部类也有这种权限)
b:外部类要访问内部类的成员,必须创建对象。(和main主方法想访问类的成员一样,需要先创建类的对象,同样,外部类的方法要访问内部类的成员也需要先创建内部类的对象,通过内部类的对象.成员来访问)
c:main方法访问内部类成员时,要通过 外部类名.内部类名 内部类对象名 = 外部类对象.内部类对象 内部类名.成员来创建。
Outer.Inner outerInner = new Outer().new Inner() //new ClassName()是创建了一个对象
inner.members //members[variables | methods]
一、成员内部类:
代码:
class Outer { private int num = 10 ; class Inner { public void method() { System.out.println(num) ; } } } public class Demo { public static void main(String [] args) { Outer.Inner outerInner = new Outer().new Inner() ; outerInner.method() ; } }
二、静态内部类:
代码:
class Outer { private static int num = 10 ; static class Inner { public void method() { System.out.println(num) ; } } } public class Demo { public static void main(String [] args) { Outer.Inner outerInner = new Outer.Inner() ; outerInner.method() ; } }
三、局部内部类:
代码:
class Outer { private int num = 10 ; public void outerMethod() { /*局部内部类要访问局部变量应该加上final,使NUM变成常量,进入方法区的常量池 *不加final,局部变量的生命周期会随着outerMethod()方法一起弹栈消失, *那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,会出现异常 *但是JDK1.8之后,取消了这个要求,不加final,也不会出现异常,这个特性是JDK1.8之后要引出Lambda表达式而作准备的 *Lambda表达式指的是应用在单一抽象方法接口环境下的一种简化定义形式,可以用于解决匿名内部类的定义复杂问题。 *在下面讲到的匿名内部类时会作一比较。 */ final int NUM = 20 ; //局部内部类要访问局部变量应该加上final,使NUM变成常量,进入方法区的常量池 class Inner { public void method() { System.out.println(num) ; System.out.println(NUM) ; } } Inner inner = new Inner() ; inner.method() ; } /*public void run() { Inner inner = new Inner(); //局部内部类,只能在其所在的方法中访问 inner.method(); }*/ } public class Demo { public static void main(String [] args) { Outer outer = new Outer() ; outer.outerMethod() ; } }
四、匿名内部类:
代码:
interface Inter { //抽象类或者接口为父类 public abstract void method() ; } class Outer { public void outerMethod() { //直接通过子类对象调用子类覆写的父类方法 new Inter() { public void method() { System.out.println("匿名内部类覆写父类方法并调用") ; } }.method() ; //匿名内部类对象调用子类覆写的method方法。匿名了,就只能用new出来的对象直接调用,只能用一次。 //直接通过子类对象调用子类自己实现的方法 new Inter() { public void method() { System.out.println("匿名内部类覆写父类方法并调用") ; } public void innerMethod() { System.out.println("匿名内部类现实自己的方法并调用") ; } }.innerMethod() ; //匿名内部类对象调用子类自己的innerMethod()方法。 //匿名内部类覆写父类方法,new(实例化)子类对象,当实参传递给fun(Inter inter)的形参 fun(new Inter() { public void method() { System.out.println("匿名内部类覆写父类方法,new(实例化)子类对象,当实参传递给fun(Inter inter)的形参") ; } }) ; //Lambda表达式代替匿名内部类覆写父类方法,当实参传递给fun(Inter inter)的形参 fun(() -> System.out.println("Lambda表达式代替匿名内部类覆写父类方法,当实参传递给fun(Inter inter)的形参")) ; } public void fun(Inter inter) { // inter.method() ; } } public class Demo { public static void main(String [] args) { Outer outer = new Outer() ; outer.outerMethod() ; } }
浙公网安备 33010602011771号