20.接口组成更新

接口组成更新

接口组成更新概述

接口的组成

  • 常量: public static final

  • 抽象方法: public abstract

  • 默认方法(java8中新增)

  • 静态方法(java8中新增)

  • 私有方法(java9中新增)

接口的默认方法

定义格式: default void 方法名() {};

MyInterface

package interfaceJava.interfaceUpdate.defaultMethod;

public interface MyInterface {
    void show1();
    void show2();
    // void show3();

    /*
    public default void show3() {
        System.out.println("show3");
    }
     */

    default void show3() {
        System.out.println("show3");
    }
}

MyInterfaceImplOne

package interfaceJava.interfaceUpdate.defaultMethod;

public class MyInterfaceImplOne implements MyInterface {
    @Override
    public void show1() {
        System.out.println("One show1");
    }

    @Override
    public void show2() {
        System.out.println("One show2");
    }

    @Override
    public void show3() {
        System.out.println("One show3");
    }
}

MyInterfaceImplTwo

package interfaceJava.interfaceUpdate.defaultMethod;

public class MyInterfaceImplTwo implements MyInterface {
    @Override
    public void show1() {
        System.out.println("Two show1");
    }

    @Override
    public void show2() {
        System.out.println("Two show2");
    }
}

MyInterfaceDemo

package interfaceJava.interfaceUpdate.defaultMethod;

public class MyInterfaceDemo {
    public static void main(String[] args) {
        //使用多台方式创建对象并使用
        MyInterface my = new MyInterfaceImplOne();
        my.show1();
        my.show2();

        my.show3();
    }
}

接口中静态方法

接口中静态方法定义格式

  • 格式: public static 返回值类型方法名(参数列表) {};

  • 范例: public static void show() {};

Inter

package interfaceJava.interfaceUpdate.staticMethod;

public interface Inter {
    void show();
    default void method(){
        System.out.println("Inter 中默认方法");
    }
    // public可以省略掉
    static void test() {
        System.out.println("Inter 中静态方法执行了");
    }
}

InterImpl

package interfaceJava.interfaceUpdate.staticMethod;

public class InterImpl implements Inter, Flyable {
    @Override
    public void show() {
        System.out.println("show 方法执行");
    }
}

Flyable

package interfaceJava.interfaceUpdate.staticMethod;

public interface Flyable {
    public static void test() {
        System.out.println("Flyable 静态方法test执行");
    }
}

InterDemo

package interfaceJava.interfaceUpdate.staticMethod;

public class InterDemo {
    public static void main(String[] args) {
        Inter i = new InterImpl();
        i.show();
        i.method();
        // i.test();  // 静态方法只能被接口调用
        Inter.test();

        // InterImpl.test();  // 实现类也不能

        Flyable.test();
        // 如果能够通过实现类调用,当实现两个接口中有重复的方法名时, 不知道该调用哪一个, 所以不能用实现类调用
    }
}

接口中私有方法

java9中新增了带方法体的私有方法. 当两个默认方法或者静态方法包含一段相同的代码实现时, 程序必然考虑将这段实现代码抽取成一个共性方法, 而这个共性方法是不需要让别人使用的, 因此用私有隐藏起来.

格式一:

  • private 返回值类型 方法名(参数列表) {}
  • private void show() {}

格式二:

  • private static 返回值类型 方法名(参数列表) {}
  • private static void method() {}

Inter

package interfaceJava.interfaceUpdate.privateMethod;

public interface Inter {
    default void show1() {
        System.out.println("show1 开始");
        // System.out.println("1");
        // System.out.println("2");
        // System.out.println("3");
        // show();
        method();
        System.out.println("show1 结束");
    }

    default void show2() {
        System.out.println("show2 开始");
        // System.out.println("1");
        // System.out.println("2");
        // System.out.println("3");
        // show();
        method();
        System.out.println("show2 结束");
    }

    static void method1(){
        System.out.println("method1 开始");
        // System.out.println("1");
        // System.out.println("2");
        // System.out.println("3");
        method();
        System.out.println("method1 结束");
    }

    static void method2() {
        System.out.println("method2 开始");
        // System.out.println("1");
        // System.out.println("2");
        // System.out.println("3");
        method();
        System.out.println("method2 结束");
    }

    private void show() {
        System.out.println("1");
        System.out.println("2");
        System.out.println("3");
    }

    private static void method() {
        System.out.println("1");
        System.out.println("2");
        System.out.println("3");
    }
}

InterImpl

package interfaceJava.interfaceUpdate.privateMethod;

public class InterImpl implements Inter {
}

InterDemo

package interfaceJava.interfaceUpdate.privateMethod;

public class InterDemo {
    public static void main(String[] args) {
        // 按照多态的方式创建类
        Inter i = new InterImpl();
        i.show1();
        System.out.println("--------");
        i.show2();
        System.out.println("--------");

        Inter.method1();
        System.out.println("--------");
        Inter.method2();
    }
}

注意:

  • 默认方法可以调用私有的静态方法和非静态方法
  • 静态方法只能调用私有的静态方法

方法引用

如果lambda中指定的操作方案, 已经有地方存在相同方案, 就没有必要重写逻辑, 这就是方法引用, 用来使用已经存在的方案

方法引用符

"::"该符号为引用运算符, 而它所在的表达式被称为方法引用

回顾一下我们在体验方法引用中的代码

  • lambda表达式: usePrintable(s -> System.out.println(s));
    • 拿到参数s后, 通过lambda表达式, 传递给System.out.println方法
  • 方法引用: usePrintable(System.out::println);

推导和省略

  • 如果使用lambda, 根据"可推导就是可省略"原则, 无需指定参数类型, 也无需指定重载形式, 他们都将被自动推导

  • 如果使用方法引用, 也是同样可以根据上下文进行推导

  • 方法引用是lambda的孪生兄弟

Printable

package methodQuote;

public interface Printable {
    void printString(String s);
}

PrintableDemo

package methodQuote;

public class PrintableDemo {
    public static void main(String[] args) {
        // 调用usePrintable
        /*
        usePrintable((String s) -> {
            System.out.println(s);
        });
         */

        usePrintable(s -> System.out.println(s));
        // System.out.println("热爱生活");

        // 方法引用符: ::
        usePrintable(System.out::println);  // 没有参数, 直接引用前面的参数
        // 可推导的就可以省略
    }

    private static void usePrintable(Printable p) {
        p.printString("热爱生活");
    }
}

lambda表达式支持的方法引用

常见的引用方式

  • 引用类方法
  • 引用对象的实例方法
  • 引用类的实例方法
  • 引用构造器

引用类方法

就是引用类的静态方法

  • 格式: 类名::静态方法
  • 范例: Integer::parseInt

Convert

package methodQuote.staticQuote;

public interface Converter {
    int convert(String s);
}

ConverterDemo

package methodQuote.staticQuote;

public class ConverterDemo {
    public static void main(String[] args) {
        // 调用convert方法
        useConverter(s -> Integer.parseInt(s));

        // 引用类方法
        useConverter(Integer::parseInt);

        // 注意: lambda表达式被类方法代替的时候, 它的形式参数全部传递给静态方法做为参数
    }
    private static void useConverter(Converter c) {
        int number = c.convert("666");
        System.out.println(number);
    }
}

引用对象的实例方法

引用类中的成员方法

  • 格式: 对象::成员方法

  • 范例: "HelloWrold"::toUpperCase

Printer

package methodQuote.methodQuote;

public interface Printer {
    void printUpperCase(String s);
}

PrintString

package methodQuote.methodQuote;

public class PrintString {
    public void printUpper(String s) {
        String result = s.toUpperCase();
        System.out.println(result);
    }
}

PrinterDemo

package methodQuote.methodQuote;

public class PrinterDemo {
    public static void main(String[] args) {
        // 调用usePrinter方法
        usePrinter((String s) -> {
            System.out.println(s.toUpperCase());
        });

        // 引用对象的实例方法
        PrintString ps = new PrintString();
        usePrinter(ps::printUpper);

        // lambda表达式被对象的实例方法替代的时候, 它的形式参数全部传递给该方法作为参数
    }

    private static void usePrinter(Printer p) {
        p.printUpperCase("HelloWorld");
    }
}

引用类的实例方法

引用类中的成员方法

  • 格式: 类名::成员方法
  • 范例: String::substring

MyString

package methodQuote.classQuote;

public interface MyString {
    String mySubString(String s, int x, int y);
}

MyStringDemo

package methodQuote.classQuote;

public class MyStringDemo {
    public static void main(String[] args) {
        // 调用useMyString方法
        /*
        useMyString((String s, int x, int y) -> {
            return s.substring(x,y);
        });
         */

        useMyString((s, x, y) -> s.substring(x, y));

        // 引用类中的实例方法
        useMyString(String::substring);

        // lambda表达式被类的实例方法替代的时候, 它的第一个参数作为调用者, 后面的参数全部传递给该方法作为参数
    }

    private static void useMyString(MyString my) {
        String s = my.mySubString("HelloWorld", 2, 5);
        System.out.println(s);
    }
}

引用构造器

引用构造方法

  • 格式: 类名::new
  • 范例: Student::new

Student

package methodQuote.constructQuote;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

StudentBuilder

package methodQuote.constructQuote;

public interface StudentBuilder {
    Student build(String name, int age);
}

StudentDemo

package methodQuote.constructQuote;

public class StudentDemo {
    public static void main(String[] args) {
        // 调用useStudentBuilder
        /*
        useStudentBuilder((String name, int age) -> {
            return new Student(name, age);
        });
         */

        useStudentBuilder((name, age) -> new Student(name, age));

        // 方法引用
        useStudentBuilder(Student::new);
        // lambda表达式被构造器替代的时候, 它的形式参数全部传递给构造器作为参数
    }

    private static void useStudentBuilder(StudentBuilder sb) {
        Student s = sb.build("林青霞", 30);
        System.out.println(s.getName() + "," + s.getAge());
    }
}
原文地址:https://www.cnblogs.com/ryxiong-blog/p/13890485.html