java - Java中的面向对象多态逻辑
问题描述
我们可以getWeight()
在两种实现中对 cat 和 dog 对象使用相同的命名方法。我找不到两个实现之间的任何区别。在这里使用多态性或覆盖有什么好处吗?
首次实施
public class Cat{
public int getWeight() { return 5; }
}
public class Dog {
public int getWeight() { return 7; }
}
public class Main {
public static void main(String [] args) {
Dog dog = new Dog();
Cat cat = new Cat();
System.out.println(dog.getWeight());
System.out.println(cat.getWeight());
}
}
第二次实施
public class Cat extends Animal{
public int getWeight() { return 5; }
}
public class Dog extends Animal{
public int getWeight() { return 7; }
}
public class Animal {
public int getWeight() return 10;
}
public class Main {
public static void main(String [] args) {
Animal dog = new Dog();
Animal cat = new Cat();
System.out.println(dog.getWeight());
System.out.println(cat.getWeight());
}
}
解决方案
如果 Cat/Dog 是 Animal 的子类型,则 Cat/Dog 类型的对象可以替换为 Animal 类型的对象(即,类型 T 的对象可以替换为子类型 S 的任何对象),而不会更改任何所需的程序的属性(正确性、执行的任务等)
这有助于遵守 LSP https://en.wikipedia.org/wiki/Liskov_substitution_principle
遵循 LSP 的代码松散地相互依赖,并鼓励代码可重用性。不遵守 LSP 的代码是紧密耦合的,会产生不必要的纠缠。在给定的情况下,如果客户不想沉迷于每种动物类型,他们可以简单地使用 Animal 变量类型。因此,使它们与实际的实现子类型分离,从而能够使用相同的代码支持任何动物的实现。
但是,在某些情况下,坚持 LSP 也会导致问题。例如: http: //www.blackwasp.co.uk/squarerectangle.aspx
覆盖的另一个优点是新的实现将更容易且更标准化。新的动物类型实施者将知道在实施过程中要注意哪些行为。
推荐阅读
- python - 拆分列表并为两个值保留唯一标识符 - python
- javascript - 如何将变量添加到值查询?火力基地
- c++ - 如何通过重载 | 链接和序列化函数 操作员
- android - 为什么 Google Flutter 中底部导航栏中的类似项目的文本大小不同?
- python - 如何使用 csv 文件向个人发送电子邮件?
- java - 程序终止后,返回到主代码的开始处或其他地方
- javascript - 如何使用正则表达式删除字符串中所有出现的重复字母。在 JS 中
- laravel - Laravel Passport 覆盖主键不起作用
- ios - SwiftUI:在用户滑动以关闭时显示警报
- scala - 将 Type1:EitherT[Future, String, Int] 转换为 Type2:EitherT[Future, String, Option[Int]] 而 Type1 中的所有 Left 在 Type2 中变为 Right(None)