当抽象 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
主要用于描述属性,如CanWalk
、IsCloseable
、HasAName
等。
从语言的角度来看,这两个概念之间没有太大区别,只是您只能从一个扩展 class 但可以实现多个接口。
在继承链的末端,您将始终拥有non-abstract具体classes。很明显,你不能最终使用未完成的 classes,你需要完成它们。这就是为什么
Animal animal = new Animal();
如果 Animal
是 abstract
, 不起作用。我们需要创建完成的 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
不是抽象的,所有的方法都需要实现。也就是说,我们需要 jump
和 makeNoise
的实现。对于 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"
.
我是 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
主要用于描述属性,如CanWalk
、IsCloseable
、HasAName
等。
从语言的角度来看,这两个概念之间没有太大区别,只是您只能从一个扩展 class 但可以实现多个接口。
在继承链的末端,您将始终拥有non-abstract具体classes。很明显,你不能最终使用未完成的 classes,你需要完成它们。这就是为什么
Animal animal = new Animal();
如果 Animal
是 abstract
, 不起作用。我们需要创建完成的 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
不是抽象的,所有的方法都需要实现。也就是说,我们需要 jump
和 makeNoise
的实现。对于 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"
.