为什么我不能在保留compareTo契约的同时使用新的值组件扩展可实例化的类?

Ken*_*ell 6 java

Joshua Blotch的每个有效Java:

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

能否请您通过实例和挑战解释上述问题?你能解释一下Joshua对"价值组件"的意义以及其他类型的组件是否可用.

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

你能解释一下约书亚在二等作为第一堂课时的意思吗?

Jon*_*eet 10

能否请您通过实例和挑战解释上述问题?

当然.考虑这样的两个类 - 我省略了所有的吸气剂,安装者等,但希望你得到漂移:

class NamedThing {
    String name;
}

class Person extends NamedThing {
    Date dateOfBirth;
}
Run Code Online (Sandbox Code Playgroud)

忽略这是否是一个很好的继承示例 - 这是一个简单的例子.

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);
Run Code Online (Sandbox Code Playgroud)

你想要所有这些结果是什么?如果Person.compareTo足够智能将其日期处理应用于实例Person,那么您可能期望comparison1并且comparison2为0,但是comparison3非零.

据推测comparison4具有为0,因为它的使用NamedThing.compareTo,这只是比较名称.

从根本上说,尝试比较不同类型的实例存在问题.它最终变得更清晰,有一个比较的外部定义,它定义了它将使用的比较.因此,您可以拥有一个Comparator<Person>只接受Person引用并使用名称和日期,以及Comparator<NamedThing>仅按名称进行比较的名称.行为将具有对称性和清晰度.

你能解释一下约书亚在二等作为第一堂课时的意思吗?

你已经脱离了背景.它是:"将第二类的实例视为第一类的实例" - 例如

// First class = Animal
// Second class = Zebra
Animal person = new Zebra();
Run Code Online (Sandbox Code Playgroud)