Mad*_*awg 6 java inheritance multiple-inheritance
我最近一直在研究抽象方法,我不明白为什么我们需要它们?我的意思是,毕竟,我们只是压倒了它们。你知道它只是一个声明吗?我们为什么需要它们?
此外,我尝试从互联网上理解这一点,到处都有解释,比如想象有一个抽象类人类,然后它的子类被禁用和未禁用,然后人类类中的抽象函数walking()
将包含不同的主体或代码。现在我要说的是为什么我们不在禁用和未禁用的子类中创建一个函数而不是覆盖。因此再次回到第一段中的问题。请解释一下。
抽象方法最明显的用途之一是让抽象类从其他方法的实现中调用它们。
下面是一个例子:
class AbstractToy {
protected abstract String getName();
protected abstract String getSize();
public String getDescription() {
return "This is a really "+getSize()+" "+getName();
}
}
class ToyBear extends AbstractToy {
protected override String getName() { return "bear"; }
protected override String getSize() { return "big"; }
}
class ToyPenguin extends AbstractToy {
protected override String getName() { return "penguin"; }
protected override String getSize() { return "tiny"; }
}
Run Code Online (Sandbox Code Playgroud)
请注意AbstractToy
的实现如何getDescription
能够调用getName
and getSize
,即使定义在子类中。这是一个著名的设计模式的实例,称为Template Method。
基类型中的抽象方法定义是一种契约,它保证该类型的每个具体实现都将具有该方法的实现。
没有它,编译器将不允许您在基类型的引用上调用该方法,因为它无法保证这样的方法将始终存在。
所以如果你有
MyBaseClass x = getAnInstance();
x.doTheThing();
Run Code Online (Sandbox Code Playgroud)
并MyBaseClass
没有有doTheThing
法,那么编译器会告诉你,它不能让你这样做。通过添加抽象 doTheThing
方法,您可以保证getAnInstance()
可以返回的每个具体实现都有一个实现,这对编译器来说已经足够好了,因此它可以让您调用该方法。
基本上一个更基本的真理,首先需要了解的是:
您将有实例,其中变量的类型比它所保存的值的类型更通用。在简单的情况下,您可以使变量成为特定类型:
MyDerivedClassA a = new MyDerivcedClassA();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您显然可以调用 的任何方法,MyDerivedClassA
并且不需要基类中的任何抽象方法。
但有时您想对任何 MyBaseClass
实例做某事,而您不知道它是什么特定类型:
public void doTheThingsForAll(Collection<? extends MyBaseClass> baseClassReferences) {
for (MyBaseClass myBaseReference : baseClassReferences) {
myBaseReference.doTheThing();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您MyBaseClass
没有doTheThing
抽象方法,那么编译器不会让您这样做。