Skip to content

在 Java 中,接口是一种定义了一组方法签名(没有实现体)的抽象类型。它提供了一种约定,规定了类应该如何与其他类进行交互。

要声明一个接口,需要使用关键字interface来修饰接口名。接口可以包含常量、抽象方法和默认方法。常量在接口中被隐式地声明为public static final,因此不允许修改其值。

抽象方法在接口中被隐式地声明为public abstract,因此子类必须实现这些方法。

默认方法是在Java 8中引入的新特性,在接口中可以提供具有默认实现的方法。默认方法使用关键字default修饰,并且可以在接口中直接调用。下面是一个简单的接口示例:

public interface Animal {
    int LEGS = 4; // 常量
    
    void makeSound(); // 抽象方法

    default void eat() { // 默认方法
        System.out.println("The animal is eating.");
    }
}

public class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks.");
    }
}

在上面的示例中,Animal 是一个接口,它包含了一个常量LEGS和一个抽象方法makeSound(),以及一个默认方法eat()。Dog 类实现了Animal接口,并实现了makeSound()方法。

通过实现接口,类可以获得接口中定义的方法,并根据需要进行具体实现。一个类可以同时实现多个接口,这样它就能够获得多个接口中定义的方法。

接口继承

在 Java 中,接口可以通过使用关键字"extends"来继承其他接口。这种继承方式允许一个接口从另一个或多个接口中继承方法签名。下面是一个示例代码,展示了如何在 Java 中实现接口的继承:

// 定义第一个接口
interface Interface1 {
    void method1();
}

// 定义第二个接口,并继承Interface1
interface Interface2 extends Interface1 {
    void method2();
}

// 实现包含两个接口的类
class MyClass implements Interface2 {
    @Override
    public void method1() {
        System.out.println("实现了method1");
    }

    @Override
    public void method2() {
        System.out.println("实现了method2");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.method1(); // 输出:实现了method1
        obj.method2(); // 输出:实现了method2
    }
}

在上面的示例中,我们定义了两个接口Interface1Interface2,其中Interface2继承自Interface1。然后我们创建了一个类MyClass,它实现了Interface2接口。最后,在主函数中,我们创建了MyClass的对象并调用了method1()method2()方法。

请注意,接口之间可以进行多重继承,即一个接口可以继承多个接口。通过接口继承,我们可以在不破坏现有接口的情况下,为接口添加新的方法签名。这样的设计使得代码更加模块化和可复用。

default 方法

在 Java 8 中,引入了接口的默认方法(Default Methods)的概念。默认方法是指在接口中提供一个已经实现的方法,这样在实现该接口的类中就不需要再次实现该方法。下面是一个示例代码,展示了如何在接口中定义和使用默认方法:

interface MyInterface {
    void method1(); // 抽象方法

    default void method2() { // 默认方法
        System.out.println("这是默认方法");
    }
}

class MyClass implements MyInterface {
    @Override
    public void method1() {
        System.out.println("实现了method1");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.method1(); // 输出:实现了method1
        obj.method2(); // 输出:这是默认方法
    }
}

在上面的示例中,我们定义了一个接口MyInterface,其中包含一个抽象方法method1()和一个默认方法method2()。然后我们创建了一个类MyClass,它实现了MyInterface接口,并只实现了抽象方法method1()。由于method2()是默认方法,在MyClass中没有重新实现该方法。

在主函数中,我们创建了MyClass的对象并调用了method1()method2()方法。注意到虽然我们没有在MyClass中实现method2()方法,但由于它是一个默认方法,所以会使用接口中提供的默认实现。

默认方法的引入使得接口可以向后兼容,即在已经存在的接口中添加新的方法时不会破坏现有的实现类。同时,默认方法也提供了一种在接口中提供通用的方法实现的方式,减少了代码重复和冗余。