Java Advanced (Third Issue): New features of the JDK version interface && Internal classes (member classes, static classes, local classes, anonymous classes) && Lambda expressions, abbreviation rules

Java Stream (Third Period)
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

Java Basics (Third Issue)

1. New features of interface

1.1 JDK8 version

Insert image description here

JDK8 version interface features:

1. 允许定义非抽象方法,但是需要加入 default 关键字 (重写方法的时候不需要)
    - 做用:解决接口的升级问题
    - 注意事项:
    		1. public 可以省略,但是default 不能省略
    		2. 默认方法:实现类是允许重写的,但是需要去掉default关键字
    		3. 如果实现了多个接口,多个接口中存在相同的默认方法,实现类必须重写默认方法
    

Code example:

package com.liujintao.jdk8;

public class InterfaceTest {
    
    
    /*
        允许在接口中定义新的抽象方法:
                需要在接口中对添加的方法加上 default 关键字
     */
    public static void main(String[] LiuJInTao) {
    
    
        Realize r = new Realize();
        r.print();  // is---print
        r.show();   // is---show
        r.method(); // is---method
        r.handle(); // is---default---eat
        r.eat();    // is---eat
    }
}

// 定义一个接口
interface Inter {
    
    
    public void show();
    public void print();

    // 在接口中添加新的抽象方法(还能带有逻辑)
    public default void method() {
    
    
        System.out.println("is---method");
    };
}

interface A {
    
    
    public void eat();

    // 接口中继续添加新的抽象方法,使用 default 修饰
    public default void handle () {
    
    
        System.out.println("is---handle");
    }
}


/**
 * 下面是实现类(多继承重写抽象方法,以及新增默认的抽象方法)
 */

// 定义第一个实现类;实现接口,并且重写里面的方法
class Realize implements Inter , A {
    
    

    @Override
    public void show() {
    
    
        System.out.println("is---show");
    }

    @Override
    public void print() {
    
    
        System.out.println("is---print");
    }

    // 重写default默认添加的抽象方法
    @Override
    public void method() {
    
    
        Inter.super.method();
        System.out.println("is---method");
    }

    // 重写A接口里面的抽象方法和默认新增方法
    public void eat () {
    
    
        System.out.println("is---eat");
    }

    public void handle () {
    
    
        System.out.println("is---default---eat");
    }
}

2. 允许定义静态方法
    - 理解:既然接口已经允许方法调用了,干脆也方法静态方法,可以使用类名调用
    
    - 注意事项:
    		1. public 可以省略,但是 static 不能省略
    		2. 接口中的静态方法,只允许接口名进行调用,不允许实现类调用
// 定义一个接口
interface A {
    
    
    public void eat();

    // 接口中继续添加新的抽象方法,使用 default 修饰
    public default void handle () {
    
    
        System.out.println("is---handle");
    }

    // 这是一个接口中的静态方法 (可以省略 public)
    public static void function () {
    
    
        System.out.println("is---A---static---function");
    }
}

// 调用接口

// 调用静态方法(接口名.方法名)调用
 A.function();
1.2 JDK9 version

Insert image description here

package com.liujintao.jdk9;

public class InterfaceDemo {
    
    
}

/**
 * 定义一个接口
 */
interface Inter {
    
    
    void show();
    void pritn();
    default void start () {
    
    
        System.out.println("开始");
        log();
    }

    default void end () {
    
    
        System.out.println("结束");
        log();
    }

    // 将重复的代码抽取出来,并私有化 (私有化不能写default)
    private void log() {
    
    
        System.out.println("记录一次");

    }
}

code block

Insert image description here

2. Internal classes

Inner class: class defined in another class

The format for creating inner class references:

外部类名.内部类名 对象名 = new 外部类名().new内部类名();
1. Member inner class

Member access details:

1. 内部类中,访问外部类成员: 直接访问,包括私有。
2. 外部类中,访问内部类成员: 需要创建对象访问。
package com.liujintao.inner;


public class InnerDemo {
    
    
    public static void main(String[] args) {
    
    
        // 创建内部类对象访问内部类中的成员:
        Inner.Inner2 i = new Inner.Inner2();
        System.out.println("user:" + i.user + "---" + "age:" + i.age);    // 访问内部类的成员(如果是private就得使用set和get)
        i.method();  // 内部类的静态方法直接类名访问;
    }
}

// 外部类
class Inner {
    
    
    private String name = "张三";
    private char gender = '男';
    // 内部类
    class Inner2 {
    
    
        private String name = "李四";
        public  String user = "admin";
        public int age = 18;
        public void method() {
    
    
            System.out.println("我是内部类的静态方法");
        }
    }
}

user:admin—age:18
I am a static method of an inner class

1.2 Inner class member access
  • In inner classes, access external class members: direct access, including private
  • In the outer class, to access the inner class members: you need to create an object to access

The following exercises will deepen your impression:

class1.class2 s = new class1().new class2();
s.shou();


class class1 {
    
    
    int num = 10;
    class class2 {
    
    
        int num = 20;
        public void shou () {
    
    
            int num = 30;
            System.out.println(num);  // 30
            System.out.println(this.num);   // 20
            System.out.println(class1.this.num);    // 10
        }
    }
}

Note: To access the external class object inside a member, you need to use: external class name.this

2. Static inner class
        静态内部类: static 修饰的成员内部类

        创建对象格式: 外部类名.内部类名 对象名 = new 外部类名(). new 内部类名()

        注意事项:静态方法智能访问静态方法(因为静态会随着类的加载而加载)
package com.liujintao.inner;

import java.sql.SQLOutput;

public class InnerDemo2 {
    
    
    public static void main(String[] LiuJinTao) {
    
    
        // 访问静态的,直接类名调用即可!
        Wai.Nei.show();


    }
}

class Wai {
    
    
    int num = 10;
    static int num2 = 20;

    // 静态内部类
    static class Nei {
    
    
        public static void show() {
    
    
            System.out.println("show------");

            Wai w = new Wai();
            System.out.println(w.num); // 10

            System.out.println(num2);   // 20
        }
    }
}

show------
10
20

3. Local class
package com.liujintao.inner;

import java.sql.SQLOutput;

public class InnerDemo3 {
    
    
    /*
        局部内部类: 放在方法、代码块、构造器等执行体中
     */
    public static void main(String [] LiuJinTao) {
    
    
        // 使用局部类
        Wai1 w = new Wai1();
        w.show(); // 里面的逻辑执行,自然访问到了method方法
    }
}

class Wai1 {
    
    
    public void show () {
    
    
        // 局部内部类
        class Nei1 {
    
    
            public void method() {
    
    
                System.out.println("method-----");
            }
        }
        Nei1 n = new Nei1();
        n.method();
    }
}

method-----

4. Anonymous inner classes (important)

Insert image description here

匿名内部类:
    	匿名内部类本质是一个特殊的局部内部类(定义在方法内部)
    	前提条件:
    			new 类名\ 接口名 () {
    
    }

				new 类名 () {
    
    }  : 代表继承这个类
                
                new 接口名 () {
    
    } : 代表实现这个接口
                    
                    
                    
 + 问题:方法的形参是接口类型,我们该传入的是什么?
+  回答:传入的是该接口的实现类对象
                    
                    + 多态的实现条件
                    接口引用需要实现类对象
                    父类引用需要子类对象
package com.liujintao.inner;

public class InnerDemo4 {
    
    
    public static void main(String[] LiuJinTao) {
    
    
        // 调用静态方法,参数需要一个接口对象(也就是实现类对象)
        method(new Inter() {
    
    
            // 实现类必须重写,要么编程抽象类
            @Override
            public void show() {
    
    
                System.out.println("我是实现类");
            }
        });
    }
    // 静态类(参数需要实现类对象) 也就是说:接口引用需要实现类对象
    public static void method(Inter i) {
    
    
        i.show();   // 我是实现类
    }
}

// 定义一个接口
interface Inter {
    
    
    public void show();
}
  • Usage scenarios: Determined based on the number of rewritten methods. If there are few overridden methods, use anonymous inner classes, otherwise use implementation classes.

Three Lambda expressions

3.1 Brief overview

Insert image description here

package com.liujintao.lambda;

public class LambdaDemo {
    
    
    public static void main(String [] LiuJinTao) {
    
    
        // 匿名类实现 (传入一个实现类对象)
        userInter(new Inter () {
    
    
            @Override
            public void show() {
    
    
                System.out.println("我是匿名类传参");
            }
        });

        // 使用Lambda表达式 实现传参
        userInter( () -> {
    
    
            System.out.println("我是Lambda表达式传参");
        });
    }

    // 定义一个静态方法
    public static void userInter (Inter i) {
    
    
        i.show();
    }
}

// 定义一个接口
interface Inter {
    
    
    void show();
}


I am passing parameters by anonymous class
I am passing parameters by Lambda expression

3.2 Lambda expression abbreviation rules

Insert image description here

  • In fact, the abbreviation rules are very similar to arrow functions.
package com.liujintao.lambda;

public class LambdaDemo2 {
    
    
    public static void main(String[] LiuJinTao) {
    
    
        userInters(new Inters () {
    
    
            @Override
            public int  getSum(int a, int b) {
    
    
                return a + b;
            }
        });

        System.out.println("------------lambda表达式实现----------");

        userInters((a, b) -> a + b);
    }

    // 定义一个静态方法(参数为一个接口引用,需要传入一个实现类对象)
    public static void userInters (Inters sum) {
    
    
        int result = sum.getSum(10, 20);  // 调用实现类中重写的方法
        System.out.println(result);
    }
}

// 定义一个接口
interface Inters {
    
    
    // 定义抽象方法的形参
    int getSum(int a, int b);
}

30
------------lambda display expression----------
30

3.3 The difference between Lambda and anonymous classesi

Insert image description here

Guess you like

Origin blog.csdn.net/Forever_Hopeful/article/details/134696929