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

时间:2018-04-10 15:22:33

标签: java

我是Java新手,来自C ++背景,我尝试理解实现接口的接口和抽象类的概念。抽象类实现接口时到底发生了什么?这是否像继承一样工作,即所有接口方法都属于abtract类,尽管它们没有在它中实现?或者只有实现的方法属于抽象类?那么实现和扩展之间有什么区别,除了一个用于实现接口而另一个用于继承?

4 个答案:

答案 0 :(得分:2)

您可以将abstract课程视为未完成课程。它就像是实际真实课程的模板。 Interface主要用于描述属性,例如CanWalkIsCloseableHasAName等。

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

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

Animal animal = new Animal();
如果Animalabstract,则

无效。我们需要创建已完成的类的实例,例如从Dog扩展的Animal

此时,如果您有已完成(非抽象)类,则需要实现所有抽象方法。无论这些方法来自何处,抽象类或接口,都需要实现它们。

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

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

实施例

假设我们有一个像

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

和抽象类

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

    ...
}

以及具体的扩展类

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的实现留给更具体的类,因为Animal不知道特定动物的声音如何。

扩展示例,如果您有更多具体的类,例如Chihuahua extends Dog,则可以在makeNoise中实现Dog,因为所有的狗都会"Wuff, wuff"

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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