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

2022-09-02 03:31:45

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


答案 1

您可以将一个类想象成一个未完成的类。它就像实际实际类的模板。s 主要用于描述属性,如 、、等。abstractInterfaceCanWalkIsCloseableHasAName

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

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

Animal animal = new Animal();

如果 为 ,则不起作用。我们需要创建已完成类的实例,例如从 扩展而来的 who。AnimalabstractDogAnimal


在这一点上,如果你有一个完成的(非抽象)类,所有抽象方法都需要实现。无论这些方法来自哪里,抽象类或接口,它们都需要实现。

因此,如果您有一个抽象类并使用它实现一个接口,则接口方法有两个选项。您要么

  • 在抽象类中实现它们,或者
  • 把它们抽象起来,但随后你的一些更具体的孩子需要实现它。

假设我们有一个这样的接口

public interface CanMakeNoise {
    void makeNoise();
}

和抽象类

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

    ...
}

与混凝土扩展类一起

public class Dog extends Animal {
    ...
}

由于不是抽象的,因此需要实现所有方法。也就是说,我们需要 和 的实现。对于该方法,我们有两个选项,要么实现它,要么让它抽象,然后需要实现它:DogjumpmakeNoisemakeNoiseAnimalDog

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

当然需要实施:Dogjump

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

    ...
}

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

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


答案 2

方法当然属于实现类。我不会说它来自哪里并不重要,因为多态性。在Java中,你没有多重继承,但你可以实现多个接口,所以这给了你更多关于层次结构的选择。


推荐