6

Joshua Blotch 的Per Effective Java

compareTo除非您愿意放弃面向对象抽象的好处,否则无法在保留契约的同时使用新的值组件扩展可实例化类

您能否通过示例和挑战解释上述内容?您能否也解释一下 Joshua 所说的“价值组件”是什么意思以及还有哪些其他类型的组件可用。

这使您可以自由地compareTo在第二个类上实现您喜欢的任何方法,同时允许其客户端在需要时将第二个类的实例视为第一个类的实例。

你能否解释一下 Joshua 所说的第二类作为第一类的实例是什么意思?

4

2 回答 2

10

您能否通过示例和挑战解释上述内容?

当然。考虑两个这样的类 - 我已经省略了所有的 getter、setter 等,但希望你能明白:

class NamedThing {
    String name;
}

class Person extends NamedThing {
    Date dateOfBirth;
}

忽略这是否是继承的一个很好的例子——它是一个简单的例子。

NamedThing按字母顺序实现基于名称的比较是很自然的。

Person实现一个比较也很自然,首先比较名称(因此在这方面保持一致),然后检查一个出生日期是否早于另一个

现在想象一下:

NamedThing person1 = new Person("Jon", date1);
NamedThing person2 = new Person("Jon", date2);
NamedThing thing = new NamedThing("Jon");

int comparison1 = person1.compareTo(thing);
int comparison2 = person2.compareTo(thing);
int comparison3 = person1.compareTo(person2);
int comparison4 = thing.compareTo(person1);

你希望所有这些结果是什么?如果Person.compareTo足够聪明,将其日期处理应用于 的实例Person,那么您可能期望comparison1andcomparison2为 0,但comparison3不为零。

大概comparison4必须0,因为它正在使用NamedThing.compareTo它只比较名称。

从根本上说,试图比较不同类型的实例是有问题的。拥有一个比较的外部定义会更清晰,它定义了它将使用什么比较。因此,您可以有一个Comparator<Person>只接受Person引用并使用名称和日期的一个,以及一个Comparator<NamedThing>只按名称比较的。该行为将具有对称性和清晰度。

你能解释一下 Joshua 所说的第二类作为第一类的实例是什么意思吗?

你已经断章取义了。它是:“将第二类的实例视为第一类的实例” - 例如

// First class = Animal
// Second class = Zebra
Animal person = new Zebra();
于 2012-11-22T09:28:31.817 回答
0
  1. 这意味着对于每个子类,您必须重写compareTo方法。
  2. 转换为超类称为向上转换
于 2012-11-22T09:42:22.447 回答