当抽象 class 实现 Java 中的接口时会发生什么

What happens when an abstract class implements an interface in Java

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

在Java中,一个class只能继承一个class,但可以实现多个接口。

抽象class与接口非常相似。主要区别在于抽象 class 已经可以定义一些函数,而接口不能(请注意,这在 Java9+ 中发生了变化)。

使用哪一个?嗯,这真的取决于你的结构,但 javadoc 定义了一些例子。

一个方法当然属于实现class。我不会说因为多态性,它来自哪里并不重要。在 Java 中,您没有 multi-inheritance,但您可以实现多个接口,因此这为您提供了有关层次结构的更多选项。

如果您担心接口的使用,那么它将用于回调,因为Java不支持函数指针。

您可以将 abstract class 想象成 未完成的 class。它就像是真实 classes 的模板。 Interface主要用于描述属性,如CanWalkIsCloseableHasAName等。

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

在继承链的末端,您将始终拥有non-abstract具体classes。很明显,你不能最终使用未完成的 classes,你需要完成它们。这就是为什么

Animal animal = new Animal();
如果 Animalabstract

不起作用。我们需要创建完成的 classes 的实例,例如从 Animal.

扩展的 Dog

到那时,你有一个 finished (non-abstract) class, all abstract methods 需要实施。不管这些方法来自哪里,抽象 classes 或接口,它们都需要被实现。

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

  • 在摘要中实现它们class
  • 让它们抽象,但是你的一些更具体的children需要实现它。

例子

假设我们有一个像

这样的界面
public interface CanMakeNoise {
    void makeNoise();
}

和摘要class

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

    ...
}

连同混凝土延伸 class

public class Dog extends Animal {
    ...
}

由于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");
    }
}

// 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");
    }
}

当然 Dog 需要实施 jump:

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

    ...
}

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

扩展这个例子,如果你有更具体的 class 像 Chihuahua extends Dog,你可以在 Dog 中实现 makeNoise 因为所有的狗都会 "Wuff, wuff".