当抽象类在 Java 中实现接口时会发生什么

Ale*_*raC 13 java inheritance interface abstract

我是 Java 新手,来自 C++ 背景,我试图理解接口和实现接口的抽象类的概念。当抽象类实现接口时到底发生了什么?这是否像继承一样工作,即所有接口方法也属于抽象类,即使它们没有在其中实现?或者只有实现的方法属于抽象类?那么implements和extends除了一个用于实现接口,另一个用于继承之外,还有什么区别吗?

Zab*_*uza 18

你可以把一个abstract类想象成一个未完成的类。它就像实际真实课程的模板。Interfaces的主要用来描述属性,如CanWalkIsCloseableHasAName等。

从语言的角度来看,这两个概念之间没有太大区别,只是您只能从一个类进行扩展,但允许实现多个接口。

继承链的末尾,您将始终拥有非抽象的具体类。很明显,你最终不能使用未完成的类,你需要完成它们。这就是为什么

Animal animal = new Animal();
Run Code Online (Sandbox Code Playgroud)

如果Animal是,则不起作用abstract。我们需要创建已完成类的实例,例如DogAnimal.


到那时,当你有一个完成的(非抽象的)类时,所有的抽象方法都需要实现。这些方法来自哪里,抽象类或接口并不重要,它们需要被实现。

所以如果你有一个抽象类并用它实现一个接口,你有两个接口方法的选择。你要么

  • 在抽象类中实现它们或
  • 让他们抽象,但是你的一些更具体的孩子需要实现它。

例子

假设我们有一个像

public interface CanMakeNoise {
    void makeNoise();
}
Run Code Online (Sandbox Code Playgroud)

和抽象类

public abstract class Animal implements CanMakeNoise {
    public abstract void jump();

    ...
}
Run Code Online (Sandbox Code Playgroud)

连同一个具体的扩展类

public class Dog extends Animal {
    ...
}
Run Code Online (Sandbox Code Playgroud)

由于Dog不是抽象的,所有的方法都需要实现。也就是说,我们需要实现jumpmakeNoise。对于makeNoise方法我们有两个选择,要么Animal实现它,要么让它抽象,然后Dog需要实现它:

// Variant 1
public abstract class Animal implements CanMakeNoise {
    public abstract void jump();

    @Override
    public void makeNoise() {
        System.out.println("hello, what's up");
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

// Variant 2
public abstract class Animal implements CanMakeNoise {
    public abstract void jump();
}

public class Dog extends Animal {
    @Override
    public void makeNoise() {
        System.out.println("Wuff wuff");
    }
}
Run Code Online (Sandbox Code Playgroud)

当然Dog需要实现jump

public class Dog extends Animal {
    @Override
    public void jump() {
        System.out.println("Boing");
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,最好将实现留给makeNoise更具体的类,因为Animal不知道特定动物的声音会是什么样子。

扩展这个例子,如果你有更具体的类,比如 a Chihuahua extends Dog,你可以实现makeNoiseinDog因为所有的狗都这样做"Wuff, wuff"