【发布时间】:2019-09-07 19:14:53
【问题描述】:
如果我有一个方法的多个实现,其中一个采用特定类的实例,另一个采用它的超类,我如何强制调用最具体的一个?
让我们看下面的代码:
public static class Cat {};
public static class DomesticCat extends Cat {};
public static class Lion extends Cat {};
public static class CatOwner {
public Cat cat;
}
public static void identifyCat(Cat cat) {
System.out.println("Generic cat");
}
public static void identifyCat(Lion lion) {
System.out.println("Lion");
}
现在如果我这样做:
identifyCat(new Cat());
identifyCat(new Lion());
identifyCat(new DomesticCat());
我明白了:
Generic cat
Lion
Generic cat
到目前为止,一切都很好,Java 选择了最具体的一个——除了匹配是基于声明的类(或我将其转换为的任何内容)完成的,而不是实际的类。例如以下代码:
Cat simba = new Lion();
identifyCat(simba);
调用identifyCat(Cat),而不是identifyCat(Lion)——因为simba被声明为Cat。
对于一个更现实的用例,让我们假设 Cat 及其所有子类都定义在一个外部库中(我无法控制),我从那里得到一个 Cat 实例,无法控制实例的实际类,例如:
Cat cat = CatFactory.getCat();
identifyCat(cat);
这将始终调用identifyCat(Cat),即使返回的Cat 实例是Lion 类型。
考虑到我可能对identifyCat() 有更多的实现,而且它们不仅仅是识别实例(例如,它们可能与该特定子类引入的成员交互):有没有一种简单的方法可以让我的代码调用identifyCat(Lion) 获取Lion(即使声明为Cat),而不求助于枚举if 语句à la if (cat instanceof Lion) identifyCat((Lion) cat)?
【问题讨论】:
-
Double Dispatch 来救援。
-
其实我觉得你的代码违反了Liskov Substitution Principle。如果对于您的业务规则,区分
Cat和Lion至关重要,那么您不应该像现在这样拥有designCat(Cat cat)。
标签: java inheritance overloading