内部类的几种使用情况(比较匿名内部类与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() ;
    }
}

 

posted on 2017-07-06 23:15  newstring  阅读(663)  评论(0)    收藏  举报