内部类

内部类

描述:内部类定义在类内部的类 本质是类使用需要创建对象
内部类存在的意义:

当目前某个类现在需要一个只能该类使用的类时

1.能修饰类的权限修饰符只能时 默认不写(default) 和公共(public)

2.内部类私有化

解释:
  • 正向思考:

    1. 四种权限修饰符常用来修饰成员 这时候时站在 的角度在看
    2. 当用来修饰类时 类的上层是 "" 此时 只有两种可能本包和其他包
    3. 默认不写 本包可见 其他包不能使用(不能导包) public 本包和其他包都能用 2个就够用了
  • 强制加其他:

    1. private 站在 的角度 私有的类 (JAVA)都没法编译,加载类 类没有存在的意义
    2. protected 站在包的角度 A类想要继承B类 (B类protected) 能继承吗? 不能 虽然protected访问的权限比default大 但是他有一个条件 存在继承关系 (这是类的角度) 也就是说 此时A应该已经是B的子类 现实情况呢 A不是B的子类 所以不能继承 不能protected修饰(修饰了就不能继承了 实际是能继承)
      比如: 你 想继承 一个百万富翁的遗产 前提是 你是他的后代 现实是你不是它的后代 所以你不能继承
  • 想不被别的类用 那么不能放外面 放里面 不想被其他类使用 那么私有化

语法:

//这是成员内部类的语法

public(或者不写) class 外部类名(){

​ private class 内部类名(){

​ }

}

内部类分类

成员内部类

位置:在成员位置的类

局部内部类

位置:方法中的类

public class Test {
    public void show() {
        int a = 10;
        class Inside {//方法中的类
            public void show() {
                System.out.println("a = " + a);//10
            }
        }
        Inside in = new Inside();//使用只能间接用 类只能在方法中使用
        in.show();
    }
    public static void main(String[] args) {
        Test t = new Test();
        t.show();
    }
}

好处

可以方便内部类直接使用外部参数 省去传参

Tips:

​ Outer.this.num Inner.this.num num 类似 "路径问题"

​ 因为我们不导包可以 用包名类的形式 使用类

当内部类时public时可以通过传参来实现

public class People {
    private String name;
    private Heart heart;
    public People(String name,Heart heart) {
        this.name=name;
        this.heart = heart;
    }
    public void show(){
        System.out.println(name+"的心脏"+heart.jumping()+"血型是:"+heart.getBloodType());
    }
    public static void main(String[] args) {
        People p = new People("小明",new Heart("A型") );
        p.show();
    }
}

匿名内部类

可参考:https://blog.csdn.net/qq_35394434/article/details/111695348

描述:匿名内部类是局部内部内的一个特例

​ 匿名 的"名"重在强调 类名 没有类名 同时直接创建时是一个没有名字的对象

本质:是一个继承了该类的子类匿名对象,或者是一个实现了该接口的实现类匿名对象

特点: 现用 现做 用完后就没了

​ 没有类 创建不了对象 创建了对象没有名字 只能用一次

语法:

//前提是:存在一个类或者抽象类或者接口
new 类名/接口名{
    重写方法;
}
public class Outer {

    public void method() {
        /*
        new Inter() { 
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        };
        */

//        show();
 //--------------------------------

        /*
        new Inter() {
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        }.show();
//--------------------------------
        */
        Inter i = new Inter() {//多态接受
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        };
        i.show();
    }
}

好处:

省去了实现类的编写

​ 使用匿名内部类时共做了三件事:

​ 1.搞了已知类的子类或者实现类

​ 2.重写了方法

​ 3.造了对象

使用场景:

匿名内部类和正常的实现接口继承父类 使用的区别

  • 当实现类确定只使用一次 使用匿名内部类 其他情况正常实现

Lambda表达式

使用条件:

  • 有一个接口
  • 接口中只能有一个抽象方法

语法:

() -> {} //()表示参数表 放形参  {} 表示方法体 重写的内容
public class EatableDemo {
    public static void main(String[] args) {
        //在主方法中调用useEatable方法
        //匿名内部类
        useEatable(new Eatable() {
            @Override
            public void eat() {
                System.out.println("一天一苹果,医生远离我");
            }
        });

        //Lambda表达式
        useEatable(() -> {
            System.out.println("一天一苹果,医生远离我");
        });
    }
    private static void useEatable(Eatable e) {
        e.eat();
    }
}

省略规则:

  • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
  • 如果参数有且仅有一个,那么小括号可以省略
  • 如果代码块的语句只有一条,可以省略大括号和分号,甚至是return

为啥可以用Lambda:可推导可省略(猜想JAVA的一种思想)

匿名内部类和Lambda的区别

  • 所需类型不同

    • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
    • Lambda表达式:只能是接口
  • 使用限制不同

    • 如果接口中仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
    • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
  • 实现原理不同

    • 匿名内部类:编译之后,产生一个单独的.class字节码文件
    • Lambda表达式:对应的字节码会在运行的时候动态生成

    推荐适用匿名内部类

    Lambda可以在写好匿名内部类的情况下使用Alt+Enter生成

posted @ 2022-06-03 22:41  ACMAN-Mr.Lee  阅读(40)  评论(0编辑  收藏  举报