我有一个任务来比较两个java对象。一个是Date
,它有日、月和年。第二个是用小时和分钟扩展它,DateT
。为了做到这一点:
- 我不能使用对象类中的任何函数。
- 我也不能在另一个类中使用一个类的名称。
- 但是我可以使用
instanceof
。
问题是,当我比较Date date
和Date dateT
(子类对象)时,我需要返回false
。
问题是date.equals(dateT)
返回true
。你有什么建议吗?
public boolean equals(Object other)
if (!(other instanceof Date))
return false;
Date d = (Date) other;
return day == d.day && month == d.month && year == d.year;
4条答案
按热度按时间u91tlkcl1#
答案应该是你不应该那样设计你的软件。不要看糟糕的例子,比如
Timestamp
以不兼容的方式扩展Date
。相反,请看像LocalDate
和YearMonth
这样的例子,它们实现了公共接口,但不是彼此的子类。但由于这是一个 * 赋值 *,这里有两种方法来解决这个问题:
问题是重写的方法是在第一个对象上调用的,这没有考虑到第二个对象可能是一个子类。因此,将比较操作拆分为两个方法,并在第二个对象上调用第二个方法:
可重写方法
equals
委托给方法参数的可重写方法,因此如果this
或参数对象是DateT
,则至少会调用一个重写方法,强制两个对象必须是DateT
才相等。当两个对象都是
DateT
时,有一个小的冗余,因为传递给sameDate
的this
已经知道是DateT
类型,但为了避免这种检查,必须将比较逻辑提取到第三种方法中,这不值得在这里付出努力。另一种方法是考虑即使
DateT
不使用day
字段,每个示例都将从Day
继承该字段。因此,用一个永远不能等于Day
示例的有效值的值来初始化它,就完成了。例如这假设一天永远不会是负数,并在构造函数中强制此属性。只有特殊的构造函数,它应该只能被子类访问,将把日期初始化为
-1
,它永远不能匹配Date
示例的有效日期。这样,Date
示例永远不会等于DateT
示例,而不需要在equals
方法中进行特殊处理。如果你有一个可变的
day
字段,必须采取额外的措施来确保没有方法可以改变这些不变量。h4cxqtbf2#
假设我理解了这个问题,我相信下面的内容应该会强制您的
equals
实现的对称和传递要求。您需要确保只比较
properly
Date to Date
和DateT to DateT
。因此,让它们各自返回自己的类名toString()
,并检查它是否与传递的对象的toString()
匹配。这只在Date
类中需要。下面的代码应该满足您的要求,因为没有
Date*
类提到其他类。因此,在
DateT
类中,但由于
DateT
是Date
的子类型,因此将其放在Date
类中注意:从Java 14开始,隐式类型转换可以如下使用:
jecbmhm33#
当你提供
DateT
类型作为equals
方法的参数时,这行if (!(other instanceof Date))
将始终为false,因为DateT
是Date
的子类。因此,return false;
将不会执行,而会检查自定义比较。在进行自定义比较之前,需要做两件事
1.检查参数是否不是
null
。null
可以传递到任何派生的数据类型变量中。1.返回
false
,如果参数不是规范名称与类名不匹配(我猜是java.util.Date
)。这就是检查相等性的方法。
qv7cva1a4#
要使用 DateT 类否定比较,可以首先检查 obj 参数是否是 DateT 的示例。
此外,这里您可以在 instanceof 语句中使用 pattern variable。
子类 equals 可以用两种方式实现,我不确定哪种更有效。
本质上,如果 DateT 类的 hours 和 minutes 为 0,则 * 可能 * 是等效的。
在这种情况下,DateT 将不等于 Date。