我正在使用Java上的OOP上的MOOC,它提供了一个我不完全理解的示例。在该示例中,Book
已创建一个类,并且他们正在为Book
该类构造“等于”重写方法。新equals()
方法采用任何对象的参数。如果该参数是Book
与该对象具有相同名称和PublishingYear
的对象,则返回true
Book
。因为参数对象可以是Object类的任何对象,所以在调用getPublishingYear()
和getName()
方法之前,如果在不在Book
类中的对象上调用该对象,则会抛出错误,因此该equals()
方法将检查以确保确实Book
通过此代码处理对象:
if (getClass() != object.getClass()) {
return false;
}
我非常了解(我认为)。我不明白的是,为什么在上面的代码之后,他们随后将参数对象转换为a
Book
,然后在新转换的对象而不是原始对象上调用getPublishingYear()
和getName()
:
Book compared = (Book) object;
if (this.publishingYear != compared.getPublishingYear()) {
return false;
}
if (this.name == null || !this.name.equals(compared.getName())) {
return false;
}
return true;
我不明白为什么如果由于上述getClass()
检查该对象不是Book类型的方法应该已经返回false,则为什么必须执行此步骤。我尝试在没有此额外转换步骤的情况下进行编译,发现该步骤确实是必需的-
如果不包括此步骤getPublishingYear()
,getName()
则编译器将显示“找不到符号”错误。那我想念什么呢?
equals()
完整的方法:
@Override
public boolean equals(Object object) {
if (object == null) {
return false;
}
System.out.println(getClass());
if (getClass() != object.getClass()) {
return false;
}
Book compared = (Book) object;
if (this.publishingYear != compared.getPublishingYear()) {
return false;
}
if (this.name == null || !this.name.equals(compared.getName())) {
return false;
}
return true;
}
将变量强制转换为数据类型基本上是告诉编译器“相信我,我知道我在做什么”。在将“对象”强制转换为“书”的情况下,您要确保编译器该对象实际上是一本书,并相应地进行操作。这也迫使您相信自己知道自己在做什么。
编辑:我不确定是否要问为什么需要实际的转换(添加“(Book)”)或为什么需要对Book变量进行赋值。我回答了前者。如果问题是后者,则答案是您需要Book变量,以便可以使用Book方法。
由于您拥有进行确定的工具,因此您会认为不需要进行强制转换,因为编译器能够生成用于确定的相同代码,只需执行赋值即可:
Book book = object; // Wrong
代替
Book book = (Book) object; // Right
如果希望编译器“仅知道”该对象是Book,则每次使用Book方法时,编译器都必须测试Object。通过在分配中明确告诉它,编译器可以创建特定于Book类的代码,而无需进一步检查Object。
问题内容: 尽管Java中的所有类都是Object类的子类,但是与其他对象类型不同,但是如果没有强制类型转换,则不能将Object类型的引用变量分配给任何其他引用类型。 例如: 问题答案: 您想知道为什么我们使用显式类型转换。这就是关于继承的一切- 让我来清除此-让我们有两个类 A类 和 B类 。和 B类 是子类的 类A 。这意味着 Class B 具有 Class A的 所有功能,这意味着 Cl
我试图抛出一个目标。但是在运行时,对象类仍然是一个派生类。 那么为什么类属性没有改变呢?
我以前做过这件事,但忘记了,无法在网上轻易找到答案。 我应该用什么类型填写?
问题内容: 我有以下代码: 注释行无法编译。 为什么即使协议要求,我也必须强制将协议类型对象强制转换为符合该对象类型的对象? 问题答案: 采用该协议告诉编译器此特定响应,至少不会更多。 在相反的结论,并 没有 成为必然。 如果受影响的类不是,约束只是编译器 在编译时 抱怨的另一信息。 在您的情况下,对编译器进行批注仅知道对作出响应。它不知道类型实际上是的子类。 因此,如果要访问具体类的属性,请不要
问题内容: 从Java 5开始,我们已经对原始类型进行装箱/拆箱,因此将其包装为,依此类推。 我最近看到许多新的Java项目(肯定要求JRE的版本至少为5,如果不是6的话)正在使用int而不是,尽管使用后者要方便得多,因为它具有一些用于转换的辅助方法到long的值等。 为什么有些人仍然在Java中使用原始类型?有什么切实的好处吗? 问题答案: 在Joshua Bloch的有效Java条款 5:“避
问题内容: 在下面的示例中(来自我的Coursepack),我们希望给该Square实例c1一些其他对象的引用p1,但前提是这两个对象是兼容类型的。 我在这里不明白的是,我们首先检查p1确实为Square,然后仍将其强制转换。如果是Square,为什么要投射? 我怀疑答案在于表观类型和实际类型之间的区别,但是我还是很困惑…… 编辑: 编译器将如何处理: Edit2: 是instanceof检查实际