如何在 Java 中测试 child class 是否相等?
How to test the child class for equality in Java?
我正在做一个项目,但遇到了一些问题。我需要测试 child class (DiscountProduct) 的相等性。
classes之间的关系可以理解为:Order class has-a Product和Product是DiscountProduct的parent。我想测试 DiscountProduct 是否相等。任何帮助深表感谢。谢谢!
下面是代码:
订单Class:
public class Order implements Comparable<Order>{
private int quantity;
//composition has-a relationship
private Product product;
public Order(int quantity, Product product) {
this.quantity = quantity;
this.product = product;
}
public boolean equals(Object obj){
if (obj instanceof Order) {
return product.equals(obj) && quantity == ((Order) obj).quantity;
}
return false;
}
public Product getProduct() {
return product;
}
}
产品class
public class Product implements Comparable<Product> {
private String productCode;
private String description;
private int unitPrice; //pence
public Product(String productCode, String description, int unitPrice) {
this.productCode = productCode;
this.description = description;
this.unitPrice = unitPrice;
}
//equals method to test product for equality.
public boolean equals(Object obj){
if (this == obj){
return true;
}
if (obj == null || !(obj instanceof Product)){
System.out.println("-");
return false;
}
Order other = (Order) obj;
if (!productCode.equals(other.getProduct().getProductCode()))
return false;
if (!description.equals(other.getProduct().getDescription()))
return false;
if (unitPrice != (other.getProduct().getUnitPrice()))
return false;
return true;
}
}
DiscountProduct class
public class DiscountProduct extends Product {
private double discountRate;
public DiscountProduct(String productCode, String description, int unitPrice, double discountRate) {
super(productCode, description, unitPrice);
this.discountRate = discountRate;
}
//equals method to test discount product for equality.
public boolean equals(Object obj){
Order other = (Order) obj;
//how to test for the equality for the discountProduct's field discountRate?
//does I need to add some method in Order class to get the discountRate of object of Order class,
//because relation is 'Order has Product' and then there is a parent-child relation
//between product and DiscountProduct class.
}
}
DiscountProduct
可以做类似的事情:
@Override // always always always use that annotation when overriding!
public boolean equals(Object obj){
.. this == obj test
if (obj == null || !(obj instanceof DiscountProduct)){
return false;
}
if (super.equals(obj)) {
cast to DiscountProduct and check discountRate
这里的重点是:
- 你真的只希望相同class的对象相等。否则很有可能你得到必要的
if a.equals(b) then b.equals(a)
规则是错误的
- 然后您想重新使用父级的现有实现 class
- 然后最后,比较子 class 字段
可能 声明 equals()
的 "last" 版本为 final
也有意义,但这实际上取决于上下文。
这部分代码:
public class Order implements Comparable<Order>{
...
public boolean equals(Object obj){
if (obj instanceof Order) {
return product.equals(obj) && ...;
}
...
}
}
A Product
与 Order
相比较。这种比较显然应该 return false
因为 Product
不是 Order
。你可能想写的是:
return product.equals(obj.product) && ...;
对您的代码的评论:有一个 contract between Object::equals
and Object::hashCode
:
The general contract of hashCode
is:
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode
method must consistently return the same integer, provided no information used in equals
comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
If two objects are equal according to the equals(Object)
method, then calling the hashCode
method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(java.lang.Object)
method, then calling the hashCode
method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
为了遵守此合同,当一个人覆盖 equals(...)
时,应该始终覆盖 hashCode()
。
我还鼓励您设置方法 equals(...)
和 hashCode()
final
。否则,可能会违反 contract of equals(...)
。
我正在做一个项目,但遇到了一些问题。我需要测试 child class (DiscountProduct) 的相等性。 classes之间的关系可以理解为:Order class has-a Product和Product是DiscountProduct的parent。我想测试 DiscountProduct 是否相等。任何帮助深表感谢。谢谢! 下面是代码:
订单Class:
public class Order implements Comparable<Order>{
private int quantity;
//composition has-a relationship
private Product product;
public Order(int quantity, Product product) {
this.quantity = quantity;
this.product = product;
}
public boolean equals(Object obj){
if (obj instanceof Order) {
return product.equals(obj) && quantity == ((Order) obj).quantity;
}
return false;
}
public Product getProduct() {
return product;
}
}
产品class
public class Product implements Comparable<Product> {
private String productCode;
private String description;
private int unitPrice; //pence
public Product(String productCode, String description, int unitPrice) {
this.productCode = productCode;
this.description = description;
this.unitPrice = unitPrice;
}
//equals method to test product for equality.
public boolean equals(Object obj){
if (this == obj){
return true;
}
if (obj == null || !(obj instanceof Product)){
System.out.println("-");
return false;
}
Order other = (Order) obj;
if (!productCode.equals(other.getProduct().getProductCode()))
return false;
if (!description.equals(other.getProduct().getDescription()))
return false;
if (unitPrice != (other.getProduct().getUnitPrice()))
return false;
return true;
}
}
DiscountProduct class
public class DiscountProduct extends Product {
private double discountRate;
public DiscountProduct(String productCode, String description, int unitPrice, double discountRate) {
super(productCode, description, unitPrice);
this.discountRate = discountRate;
}
//equals method to test discount product for equality.
public boolean equals(Object obj){
Order other = (Order) obj;
//how to test for the equality for the discountProduct's field discountRate?
//does I need to add some method in Order class to get the discountRate of object of Order class,
//because relation is 'Order has Product' and then there is a parent-child relation
//between product and DiscountProduct class.
}
}
DiscountProduct
可以做类似的事情:
@Override // always always always use that annotation when overriding!
public boolean equals(Object obj){
.. this == obj test
if (obj == null || !(obj instanceof DiscountProduct)){
return false;
}
if (super.equals(obj)) {
cast to DiscountProduct and check discountRate
这里的重点是:
- 你真的只希望相同class的对象相等。否则很有可能你得到必要的
if a.equals(b) then b.equals(a)
规则是错误的 - 然后您想重新使用父级的现有实现 class
- 然后最后,比较子 class 字段
可能 声明 equals()
的 "last" 版本为 final
也有意义,但这实际上取决于上下文。
这部分代码:
public class Order implements Comparable<Order>{
...
public boolean equals(Object obj){
if (obj instanceof Order) {
return product.equals(obj) && ...;
}
...
}
}
A Product
与 Order
相比较。这种比较显然应该 return false
因为 Product
不是 Order
。你可能想写的是:
return product.equals(obj.product) && ...;
对您的代码的评论:有一个 contract between Object::equals
and Object::hashCode
:
The general contract of
hashCode
is:
Whenever it is invoked on the same object more than once during an execution of a Java application, the
hashCode
method must consistently return the same integer, provided no information used inequals
comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.If two objects are equal according to the
equals(Object)
method, then calling thehashCode
method on each of the two objects must produce the same integer result.It is not required that if two objects are unequal according to the
equals(java.lang.Object)
method, then calling thehashCode
method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
为了遵守此合同,当一个人覆盖 equals(...)
时,应该始终覆盖 hashCode()
。
我还鼓励您设置方法 equals(...)
和 hashCode()
final
。否则,可能会违反 contract of equals(...)
。