我想知道为什么Object.Equals(Object obj)
是虚拟的。我知道我们可以覆盖该方法并编写我们自己的代码来检查相等性,而不是仅检查引用相等性的基本Object.Equals(Object obj)
方法。
我说的是为什么在我可以在我定义的类型中实现自己的新方法时覆盖它?有什么特别的原因吗?
答案 0 :(得分:1)
您将覆盖它的原因与您希望覆盖任何方法的原因相同,而不是在派生类中使用新方法隐藏它:因为多态性。您不知道您的派生类将如何被其他可能只知道基类的代码使用。
客户可能根本不知道您已经覆盖了该类,但他们 知道他们可以在您的实例上调用Equals
,因为所有内容都来自Object
。如果你有其他一些新方法,使用你的实例的代码将不会知道调用该方法。这是Liskov Substitution Principle正在发挥作用。
答案 1 :(得分:1)
我说的是为什么当我可以在我定义的类型中实现我自己的新方法时覆盖它?
因为这就是语言功能的设计方式,因为您知道C#中的每个类型都继承自TextField tf = new TextField() {
@Override
public void paste() {
super.paste();
System.out.println("text pasted in");
}
}
而Object
定义了使用默认实现来检查两个对象相等的方法,而我们因为开发人员创建新类型可能想要修改equals方法比较特定类型的两个对象的行为。
以下是一个了解虚拟原因的示例:
Object
int i = 1;
int j = 1;
Object o = i;
o.Equals(j); // now what will happen here if you have'nt overriden it
类型包含int
方法的覆盖实现,该方法检查两个整数是否相等,因此当我们使用Equals
类型的引用调用Equals
方法时将调用Object
类型中定义的实现,我们在System.Int32
中定义了一个新方法,而不是覆盖System.Int32
的{{1}}方法,然后我们会看到意外的作为Equals
类型实现的行为将检查内存地址,即引用相等。
同样考虑这个例子:
Object
如果我希望Object
方法不通过引用比较它们,但我们希望根据public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
}
public Person(string name)
{
_name = name;
}
public override string ToString()
{
return _name;
}
}
比较它们,那么我们需要Equals
name
1}}方法,以便使用override
类型引用或Equals
类型引用调用它将返回相同的结果,即不检查引用相等但检查两个Object
Person
} class objects。