• Java基础教程(17)--接口


      就像类一样,接口也是引用类型。它可以包含常量,方法签名,默认方法,静态方法和嵌套类型。在接口中,只有默认方法和静态方法有方法体。但不同于类,接口无法实例化,它只能被类实现或被其他接口继承。

    一.定义接口

      接口的定义由修饰符、关键字interface、接口名、extends关键字(接口可以继承并且支持多继承)和若干继承的父接口(如果有的话)以及接口体组成,语法如下(方括号表示可选内容):

    public interface DoIt [extends Interface1, Interface2, ...] [throws Exception1, Exception2, ...] {
        void doSomething (int i, double x);
        int doSomethingElse(String s);
    }
    

      public修饰符代表这个接口可以在任何地方使用。如果没有指定接口是public的,那么这个接口只能在定义这个接口的包中使用。
      一个接口可以继承其他接口,就像一个类可以继承另外一个类一样。不同的是,一个类只能继承一个父类,而一个接口可以继承多个接口。
      接口体包含了若干个抽象方法,从Java8之后,接口中还可以包含默认方法和静态方法。抽象方法后直接跟分号,没有大括号,因为抽象方法不包含实现。默认方法使用default关键字定义,静态方法使用static关键字定义。接口中的所有方法都默认且必须是public的,因此可以省略方法前的public。
      此外,接口可以包含常量声明。在接口中定义的所有常量都默认是public,static和final的,因此可以省略这些修饰符。

    二.实现接口

      要实现接口,需要在定义类时在类名后面使用implements关键字,然后跟着以逗号分隔的要实现的接口列表。按照惯例,如果类既继承了父类,又实现了接口,implements语句应该放在extends语句后面。
      下面定义了一个USB接口:

    public interface USB {
        void read();
        void write();
    }
    

      如果一个类实现了某个接口,则它必须实现这个接口中所有的抽象方法。假设现在我们要定义一个U盘类,它需要实现USB接口,那么它必须实现USB接口中定义的read和write方法:

    public class UDisk implements USB {
        @Override
        public void read() {
            System.out.println("Reading UDisk...");
        }
    
        public void write() {
            System.out.println("Writing UDisk...");
        }
    }
    

      当定义了一个新的接口时,实际上就是定义了一个新的引用数据类型。如果定义了一个接口类型的变量,则这个变量只能引用实现了这个接口的类的实例。例如:

    USB usb = new UDisk();
    

      若接口的抽象方法中包含异常,那么在实现这个抽象方法时可以抛出异常列表中的全部或部分异常,以及这些异常的子类,甚至不抛出异常。有关异常的知识将会在后面的文章中进行介绍。

    三.接口中的静态方法

      和类一样,接口也可以有静态方法。不同的是,在类中,既可以通过定义静态方法的类及其子类调用静态方法,也可以通过该类和子类的实例调用静态方法(可以但不推荐);在接口中,则只能通过定义静态方法的接口去调用静态方法,而不能通过实现它的类及其实例调用静态方法。接口的静态方法仅对于接口本身可见。例如下面的接口:

    public interface Bar {
        static void foo() {
            System.out.println("I'm a static method.");
        }
    }
    

      可以通过Bar.foo()的形式调用这个静态方法。假设有个BarImpl实现了这个接口,那么无论是BarImpl.foo()或new BarImpl().foo()都会产生编译错误,因为这个静态方法对它们来说是不可见的。

    四.默认方法

      从Java8之后,可以为接口中的方法提供一个默认实现。使用关键字default来表示这是一个默认方法。例如:

    public interface Comparable<T> {
        default int compareTo(T other) {
            return 0;
        }
    }
    

      当然,这里的默认方法并没有太大用处,因为Comparable的每一个实现类都要覆盖这个方法。不过有些情况下,默认方法可能很有用。如果希望在发生鼠标点击事件时得到通知,就要实现一个包含5个方法的接口:

    public interface MouseListener {
        void mouseClicked(MouseEvent event);
        void mousePressed(MouseEvent event);
        void mouseReleaseed(MouseEvent event);
        void mouseEntered(MouseEvent event);
        void mouseExited(MouseEvent event);
    }
    

      大多数情况下,我们只关心其中的一两个事件。可以将所有方法声明为默认方法,这些默认方法什么也不做:

    public interface MouseListener {
        default void mouseClicked(MouseEvent event) {}
        default void mousePressed(MouseEvent event) {}
        default void mouseReleaseed(MouseEvent event) {}
        default void mouseEntered(MouseEvent event) {}
        default void mouseExited(MouseEvent event) {}
    }
    

      这样一来,实现这个接口时,只需要覆盖真正关心的事件方法就可以了。
      默认方法可以调用其他的默认方法、静态方法和抽象方法。例如,Collection接口可以定义一个便利方法:

    public interface Collection {
        int size();
        default boolean isEmpty() {
            return size() == 0;
        }
    }
    

      这样在实现Collection接口时就不用操心isEmpty方法了。
      默认方法的一个重要用法是“接口演化”。以Collection接口为例,这个接口作为Java的一部分已经很多年了。后来,在Java8中,又为这个接口增加了一个stream方法。假设stream不是一个默认方法,那么其他已经实现了Collection接口的类将不能编译,因为要实现接口就必须实现接口所有的抽象方法。这样一来,就要修改其他所有已经实现了Collection接口的类的代码,这显然不是我们愿意看到的。
      不过,如果我们为stream方法提供默认实现,那么问题就迎刃而解了。其他已经实现了Collection接口的类不用做任何修改,就可以通过编译,而且还可以在这些类的实例上调用stream方法。如果真的有部分类需要重新定义stream方法而不是使用默认的stream方法,那么工作量也会小很多。
      下面来讨论默认方法的继承问题。当一个接口继承一个包含默认方法的接口时,可以执行以下操作:

    1. 不做任何修改,完全继承父接口的默认方法;
    2. 重新声明这个默认方法,使它变成抽象方法;
    3. 重写这个默认方法。

      执行第1种和第3种操作时,接口的实现类既可以选择使用默认的实现,也可以覆盖这个默认的方法。但执行第2种操作时,则必须实现这个抽象方法。

  • 相关阅读:
    留言板
    移动端开发
    css3的伪类
    JQuery移除事件
    关于offset,你知道多少?
    关于section-scroll插件:
    jQuery响应式弹出层和对话框插插件magnific-popup.css
    col-lg-8 col-lg-offset-2
    关于渐变属 gradient:
    关于 window.onresize
  • 原文地址:https://www.cnblogs.com/maconn/p/10204895.html
Copyright © 2020-2023  润新知