当前位置: 首页 > 知识库问答 >
问题:

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

宗政坚白
2023-03-14

根据Joshua Blotch的有效Java:

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

你能用例子和挑战来解释以上内容吗?你能解释一下Joshua所说的“价值成分”是什么意思,以及还有哪些其他类型的成分可用吗。

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

你能解释一下约书亚所说的“第二类”是指“第一类”吗?

共有2个答案

伏欣悦
2023-03-14
  1. 这意味着对于每个子类,必须重写compareTo方法
  2. 向超类投射称为向上投射
商宝
2023-03-14

你能用例子和挑战来解释以上内容吗?

当然。考虑像这样的两个类——我忽略了所有的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的实例,那么您可能期望比较1比较2为0,但比较3为非零。

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

从根本上说,试图比较不同类型的实例是一个问题。比较的外部定义最终会更简洁,定义了它将使用的比较。因此,您可以有一个比较器

你能解释一下约书亚所说的“第二类”是指“第一类”吗?

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

// First class = Animal
// Second class = Zebra
Animal person = new Zebra();

 类似资料:
  • Joshua Blotch的《有效Java》中写道: 除非您愿意放弃面向对象抽象的好处,否则在保留

  • 我正在创建一个Minecraft 1.12.2 mod(forge 1.12.2-14.23.1.2555),并创建了一个扩展ItemAxe的新类。当我将新类实例化为变量时,该变量返回null。因此,在注册该项时,会引发NullPointerException。在我尝试将ItemAxe的扩展名改为ItemAxe之后,我开始考虑这个问题。运行了代码,它成功了。将其更改回ItemAxe,运行代码,但不

  • 问题内容: 我明白: 由于抽象类本身并不是什么,例如车辆,我们想要创建一个具体实现的对象,例如Car,Bike等。 对象链期间将调用抽象类的构造函数。 我们永远不能直接创建抽象类的对象,即使它包含构造函数并且所有方法都已实现。 但是从编译器的角度来看,Java为什么要强制执行这些规则? 问题答案: 这不是技术限制,而是(如您所指出的)逻辑上的限制。Java(和许多其他语言)执行各种规则不是因为它们

  • 类别:账户余额 我已经把这两个类都放在Balance.java和Account tBalance.java.这两个文件都在E:/程序/MyPack. Balance.java编译没有错误但是当我编译Account tBalance.java它给出错误:找不到符号"平衡". 我无法弄清楚为什么当两个类都在同一个包中声明时? 我正在使用javac B从MyPack编译alance.javajavac

  • 我有以下功能: <代码>坐标 这是它的重载==运算符: 如果(c==i),它会在以下位置给我一个错误: 错误:传递“常量坐标”

  • 我已经完成了一些Java教程,它们都说在调用类时创建一个新变量。这是为什么?我已经测试了一些代码,但它没有这样做。我已经使用python很长一段时间了,所以我习惯于使用动态语言。 请看下面我一直在玩的一些代码: 谢谢你的时间。