Per Joshua Blotch 的《Effective Java》:
无法用新值扩展可实例化类 组件,同时保留
合约,除非您是 愿意放弃面向对象抽象的好处compareTo()
您能否通过示例和挑战来解释上述内容? 您还能解释一下 Joshua 所说的 “价值组件” 是什么意思以及还有哪些其他类型的组件可用?
这可以让你自由地实现你喜欢的任何
方法 第二类,同时允许其客户端查看 需要时,第二类作为第一类的实例。compareTo
你能否解释一下约书亚所说的“第二类作为第一类的实例”?
您能否通过示例和挑战来解释上述内容?
当然。考虑这样的两个类 - 我省略了所有的 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
足够聪明,能够 only 将其日期处理应用于 Person
的实例,那么您可能会期望 comparison1
和 comparison2
为 0,但 comparison3
为非零。
大概
comparison4
have 为 0,因为它使用 NamedThing.compareTo
,仅比较名称。
从根本上来说,尝试比较不同类型的实例存在一个问题。它最终会更清晰地定义比较的“外部”,它定义了它将使用什么比较。因此,您可以有一个仅接受 Comparator<Person>
引用并使用名称和日期的
Person
,以及仅按名称进行比较的
Comparator<NamedThing>
。该行为将具有对称性和清晰度。
你能解释一下约书亚所说的第二类作为第一类的实例是什么意思吗?你断章取义了。它是:“将第二类的实例视为第一类的实例” - 例如
// First class = Animal
// Second class = Zebra
Animal person = new Zebra();
compareTo
方法。