接口的使用

223 阅读4分钟

接口的使用

  1. 接口使用 interface 来定义

  2. Java中,接口和类是并列的两个结构

  3. 接口中不能定义构造器,接口不可以实例化。

  4. Java开发中,接口通过让类去实现(implement)的方式来使用

    • 如果实现类实现了所有的抽象方法,则实现类就可以实例化

    • 如果实现类没有实现所有的抽象方法,此实现类仍是抽象类

  5. 如何定义接口:定义接口中的成员

    1. JDK7及以前:只能定义全局常量和抽象方法

      • 全局常量:public static final 的格式,但是可以省略不写

      • 抽象方法:public abstract 的格式,但是可以省略不写

        public class test {
            public static void main(String[] args) {
                People p1 = new People();
                p1.speakOut();/* interface speak */
                p1.yell();/* speak */
            }
        }
        
        interface Speak {
            // 全局常量
            public static final String sentence = "interface speak";
            String word = "speak";
        
            // 抽象方法
            public abstract void speakOut();
            void yell();
        }
        
        class People implements Speak {
            public People() {
        
            }
        
            @Override
            public void speakOut() { // 实现接口的抽象方法
                System.out.println(sentence);
            }
        
            @Override
            public void yell() { // 实现接口的抽象方法
                System.out.println(word);
            }
        }
        
    2. JDK8:能定义全局常量和抽象方法,还可以定义静态方法和默认方法

      • 接口中定义的静态方法,只能通过接口来调用:接口名 . 方法名

      • 通过是实现类的对象,可以调用接口中的默认方法。如果实现类重写了默认方法,将调用重写后的默认方法。

      • 如果接口和父类中有同名同参数的方法。子类(实现类)会调用父类的同名同参数方法。

      • 如果两个接口中有同名同参数的方法并且接入了同一个实现类中,并且同名同参数的方法没有在实现类中被重写或实现类继承的父类中也没有同名同参数的方法,会报错。

      • 如果想要调用父类中的同名同参数方法,可以用 super . 方法名 来调用

      • 如果想调用接口中的同名同参数方法,可以用 接口名 . super . 方法名 来调用

        public class test {
            public static void main(String[] args) {
                SubClass subClass = new SubClass();
                subClass.method2(); // 通过是实现类的对象,可以调用接口中的默认方法。如果实现类重写了默认方法,将调用重写后的默认方法。
                CompareA.method1(); // 接口中的静态方法只能被接口调用
                subClass.myMethod();
            }
        }
        class SubClass extends SuperClass implements CompareA,CompareB {
            // 因为实现类继承的父类中有同名同参数的方法,所以优先使用父类中的同名同参数方法,不会报错。
            public void myMethod() {
                super.method2(); // 调用父类的同名同参数方法
                CompareA.super.method2(); // 调用CompareA接口的同名同参数方法
                CompareB.super.method2(); // 调用CompareB接口的同名同参数方法
            }
        }
        
        
        
        class SuperClass {
            public void method2() {
                // 如果接口和父类中有同名同参数的方法。子类(实现类)会调用父类的同名同参数方法。
                System.out.println("父类的默认发方法");
            }
        }
        
        interface CompareA {
            public static void method1() {
                System.out.println("静态方法");
            }
        
            public default void method2() {
                System.out.println("默认方法");
            }
        }
        
        interface CompareB {
            public static void method1() {
                System.out.println("静态方法");
            }
        
            public default void method2() {
                System.out.println("默认方法");
            }
        }
        
  6. Java类可以实现多个接口 --->弥补了Java的单继承性

    • 先写继承后写接口

      public class test {
          public static void main(String[] args) {
              People p1 = new People();
              p1.process();
          }
      }
      
      interface Speak {
          // 全局常量
          String sentence = "interface speak";
      
          // 抽象方法
          void speakOut();
      }
      
      interface Run {
          void running();
      }
      
      interface Sleep {
          void sleeping();
      }
      
      class People extends Object implements Speak, Run, Sleep { // 先写继承,后写接口。多个接口用逗号隔开。
          public People() {
          }
      
          @Override
          public void speakOut() { // 实现接口的抽象方法
              System.out.println(sentence);
          }
      
          @Override
          public void running() {
              System.out.println("running");
          }
      
          @Override
          public void sleeping() {
              System.out.println("sleeping");
          }
      
          public final void process() {
              this.speakOut();
              this.running();
              this.sleeping();
          }
      }
      

      结果:

      interface speak
      running
      sleeping
      
  7. 接口与接口之间可以继承,并且是多继承

    public class test {
        public static void main(String[] args) {
            People p1 = new People();
            p1.process();
        }
    }
    
    interface Speak {
        void speakOut();
    }
    
    interface Run {
        void running();
    }
    
    interface Sleep extends Speak, Run { // 这个接口继承了另外两个接口
        void sleeping();
    }
    
    class People implements Sleep { // 这个类实现了一个接口以及这个接口继承的其他接口的所有东西。
        public People() {
        }
    
        @Override
        public void speakOut() { // 实现接口的抽象方法
            System.out.println("speak");
        }
    
        @Override
        public void running() {
            System.out.println("running");
        }
    
        @Override
        public void sleeping() {
            System.out.println("sleeping");
        }
    
        public final void process() {
            this.speakOut();
            this.running();
            this.sleeping();
        }
    }
    

    结果

    speak
    running
    sleeping
    
  8. 接口的具体使用,体现了多态性。

  9. 接口实际可以看作一种规范。

  10. 开发中,体会面相接口编程。

    public class test {
        public static void main(String[] args) {
            Computer com = new Computer();
            Flash flash = new Flash();
            com.transferData(flash);
            System.out.println("------------------------------");
            Printer printer = new Printer();
            com.transferData(printer);
        }
    }
    
    class Computer {
        public void transferData(USB usb) { // 实现类通过传递接口来达到不同对象的最终情况
            usb.start();
            usb.work();
            usb.stop();
        }
    }
    
    interface USB { // 接口规范了 USB 的工作流程
        void start();
    
        void work();
    
        void stop();
    }
    
    
    class Flash implements USB { // 通过不同的类接入接口,会有不同的情况发生,称为接口的多态性
        @Override
        public void start() {
            System.out.println("Flash Start");
        }
    
        @Override
        public void work() {
            System.out.println("Flash work");
        }
    
        @Override
        public void stop() {
            System.out.println("Flash stop");
        }
    }
    
    class Printer implements USB { // 通过不同的类接入接口,会有不同的情况发生,称为接口的多态性
        @Override
        public void start() {
            System.out.println("Printer Start");
        }
    
        @Override
        public void work() {
            System.out.println("Printer work");
        }
    
        @Override
        public void stop() {
            System.out.println("Printer stop");
        }
    }
    
  11. 个人总结

    • 接口可以看成是abstract、static、final的终极融合版
    • 一般接口对应的多态理解为 abstract 的多态升级版
    • 日后编程尽量对接口能有更多的使用。