zoukankan      html  css  js  c++  java
  • 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());
        }
    }
    
  • 相关阅读:
    Spring 中的重试机制,简单、实用!
    Docker 常用命令,还有谁不会?
    Java 对象不使用时为什么要赋值为 null?
    为什么 Nginx 比 Apache 更牛叉?
    你还在用命令看日志?快用 Kibana 吧,一张图片胜过千万行日志!
    golang如何体现面向对象思想
    golang 三⾊标记+GC混合写屏障机制
    Golang中逃逸现象-变量何时 栈何时堆
    golang调度器原理与GMP模型设计思想
    golang 程序内存分析方法
  • 原文地址:https://www.cnblogs.com/ryxiong-blog/p/13890485.html
Copyright © 2011-2022 走看看