为什么扩展抽象 class 来更改函数定义,当我可以简单地使用方法覆盖时?
Why extend abstract class to change function definition, when I can simply use method overriding?
假设我有一只动物 class,并且我希望每种动物都有不同的 classes 和功能。有两种方法可以做到这一点:
通过继承覆盖的方法:
public class Animal {
public void sound() {}
}
public class Dog extends Animal {
public void sound() {
System.out.println("bark");
}
}
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound();
}
通过扩展 Animal
摘要 class:
abstract public class Animal {
abstract public void sound();
}
public class Dog extends Animal {
public void sound() {
System.out.println("bark");
}
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound();
}
那么,当第一种方法完成完全相同的事情时,为什么我们要使用抽象 classes 呢?我理解为什么我们使用接口 - 它建立了一个契约,任何 class 实现它都必须具有特定的方法和属性。但是,如果通过简单的继承就可以实现同样的事情,那么抽象 class 有什么用呢?
关于抽象 class 的重要一点 - 它 无法实例化 。因此,根据您的问题的性质,有时您会想要使用它。
动物实际上就是一个很好的例子:
因为世界上没有个个动物,但是个个特定的只有动物。所以 - 你会想要一个抽象 class Animal
和特定的动物 classes 将扩展它,并实现它的抽象方法。
此外,您可以在抽象 class 非抽象方法中使用这些方法 - 当扩展它的每个 class 都有 shared/common 行为时,您可以使用这些方法。
有一些基本概念因不使 Animal 抽象或接口而被破坏。我推荐你阅读 here.
举个例子说明为什么你发布的层次结构在你的场景中是错误的。任何人都可以这样做:
Animal noanimal = new Animal();
noanimal.sound();
完全没有意义; animal 在您的场景中是抽象的,而不是具体的。您不应该能够实例化 "Animal",而是它的具体实现之一。
另外,从你的场景来看,Animal应该是一个接口。它没有提供任何由其子级共享的通用实现(即使是,我也会将 Animal 保留为接口并且只有一个 BaseAnimal 抽象 class;或者只是使用组合,但这超出了这个问题的范围).
假设我有一只动物 class,并且我希望每种动物都有不同的 classes 和功能。有两种方法可以做到这一点:
通过继承覆盖的方法:
public class Animal { public void sound() {} } public class Dog extends Animal { public void sound() { System.out.println("bark"); } } public static void main(String[] args) { Animal dog = new Dog(); dog.sound(); }
通过扩展
Animal
摘要 class:abstract public class Animal { abstract public void sound(); } public class Dog extends Animal { public void sound() { System.out.println("bark"); } } public static void main(String[] args) { Dog dog = new Dog(); dog.sound(); }
那么,当第一种方法完成完全相同的事情时,为什么我们要使用抽象 classes 呢?我理解为什么我们使用接口 - 它建立了一个契约,任何 class 实现它都必须具有特定的方法和属性。但是,如果通过简单的继承就可以实现同样的事情,那么抽象 class 有什么用呢?
关于抽象 class 的重要一点 - 它 无法实例化 。因此,根据您的问题的性质,有时您会想要使用它。
动物实际上就是一个很好的例子:
因为世界上没有个个动物,但是个个特定的只有动物。所以 - 你会想要一个抽象 class Animal
和特定的动物 classes 将扩展它,并实现它的抽象方法。
此外,您可以在抽象 class 非抽象方法中使用这些方法 - 当扩展它的每个 class 都有 shared/common 行为时,您可以使用这些方法。
有一些基本概念因不使 Animal 抽象或接口而被破坏。我推荐你阅读 here.
举个例子说明为什么你发布的层次结构在你的场景中是错误的。任何人都可以这样做:
Animal noanimal = new Animal();
noanimal.sound();
完全没有意义; animal 在您的场景中是抽象的,而不是具体的。您不应该能够实例化 "Animal",而是它的具体实现之一。
另外,从你的场景来看,Animal应该是一个接口。它没有提供任何由其子级共享的通用实现(即使是,我也会将 Animal 保留为接口并且只有一个 BaseAnimal 抽象 class;或者只是使用组合,但这超出了这个问题的范围).