Java中的内部类————以及jdk1.8的lambda表达式

一.内部类学习导图

1>.静态内部类:

使用static修饰符来修饰内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。因此使用static修饰的内部类被称为静态内部类。

public class StaticInclass {
    private static int num;
    private int num1;
    private static int num2;
    /*
     * 创建一个静态内部类
     * 静态内部类可以包含静态成员,也可以包含非静态成员。
     * 根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。
     * 即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。
     */
    static class InClass{//静态内部类访问权限为包访问权限
        private int num;//静态内部类中出现了非静态变量,必须将静态内部类实例化后才能获得
        private static int num1;//静态变量
        public void f() {
            System.out.println(num2);
            System.out.println(this.num);//获取了内部类的num符合就近原则
            System.out.println(StaticInclass.num);//可以获取静态变量
//            System.out.println(StaticInclass.num1);非静态方法无法获取外部类的非静态变量
        }
        public  static void f1() {
            System.out.println(StaticInclass.num);//可以获取静态变量
//            System.out.println(StaticInclass.num1);静态方法同样无法获取外部类的非静态变量
        }
        public int getNum() {
            return num;
        }
    }
    public void f() {
        System.out.println(InClass.num1);//内部类的静态成员变量
        System.out.println(new InClass().num);//将静态内部类实例化
    }
    public static void main(String[] args) {
        /*
         * 外部类对静态内部类调用方式
         */
        StaticInclass s=new StaticInclass();
        
    }
}

注意点:

1.静态内部类允许拥有非静态变量,但是在获得静态内部类的非静态变量,必须将静态内部类实例化。

System.out.println(new InClass().num);//将静态内部类实例化获得其非静态变量

2.静态内部类只能外部类的静态变量,无法获得非静态变量。

//            System.out.println(StaticInclass.num1);静态方法同样无法获取外部类的非静态变量
//            System.out.println(StaticInclass.num1);非静态方法无法获取外部类的非静态变量

2>.非静态内部类

非静态内部类注意一点:内部类获取外部类的变量:“外部类.this.变量名”

代码:

package com.cjm.inclass;

public class InClassText {
    int num;

    public InClassText(int num) {
        this.num = num;
    }

    public class InClass {
        int num;

        public InClass(int num) {
            this.num = num;
            System.out.println(InClassText.this.num);//获取了外部类的变量
        }

        @Override
        public String toString() {
            return "内部类的num:" + this.num;
        }
    }

    @Override
    public String toString() {
        return "外部类的num:" + this.num ;
    }

    public static void main(String[] args) {
        InClassText inclasstext = new InClassText(0);//外部类的初始化
        InClassText.InClass inclass = inclasstext.new InClass(10);//内部类的初始化
    }
}

3>.局部内部类

创建在方法或者代码块中的内部类为局部内部类

4>.匿名内部类

 个人认为匿名内部类存在着打乱Java代码整体规则,使得代码混乱的问题,强烈推荐使用lambda表达式来代替匿名内部类。

 匿名内部类的语法有些特别,创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。因此匿名内部类适合创建那种只需要一次使用的类。

         匿名内部类的格式如下:

new 父类构造器|实现接口(){

         //匿名内部类的类体部分

}

匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,实现一个接口。

  • 匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。
  • 匿名内部类不能定义构造器,因为匿名内部类没有类名,也就无法定义构造器,但是匿名内部类可以定义实例初始化块,通过初始化块来完成初始化操作。
package com.cjm.inclass;

/**
 * 匿名内部类
 * 
 * @author 小明
 *
 */
public class NoInClass {

    public Myinterface getOne() {//创建一个匿名内部类,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,实现一个接口。
        return new A() {
            /*
             * 在A类中进行添加的方法无法实现
             */
            private int num = 10;
            public void f3() {
                System.out.println("f3()");
            }
        };
    }

    public static void main(String[] args) {
        NoInClass a=new NoInClass();
        Myinterface ain=a.getOne();
        ain.f();
        Myinterface.f2();
    }
}
interface Myinterface {
    void f();
    int num=0;
    static void f2(){//匿名内部类无法使用静态方法,对象无法调用静态方法
        System.out.println("hello");
    }
}
class A implements Myinterface{
    @Override
    public void f() {
        // TODO Auto-generated method stub
        System.out.println("重写了f方法!");
    }
    
    
}
原文地址:https://www.cnblogs.com/SAM-CJM/p/9398309.html