等于方法继承混淆

时间:2014-03-03 18:49:20

标签: c# inheritance

假设我有一个类ClassB,它通过添加另一个不在ClassA中的属性来扩展另一个类ClassA。以下是等于方法的工作吗?

public bool Equals(ClassB other)
{
    return this.ExtraProp == other.ExtraProp && base.Equals(ClassB);
}

为什么我应该被允许将ClassB对象传递给ClassA的equals方法(只接受ClassA个对象)?这只是继承的工作原理吗?

2 个答案:

答案 0 :(得分:6)

因为ClassB对象一个ClassA对象。您可以随时随地将ClassB对象视为ClassA对象。这是多态性的本质。

至于它是否真的会返回正确的结果,这取决于你ClassA的实现。某些实现不会像这个代码期望的那样工作,但其他实现会。

我们在这里使用一个具体的例子。让我们说这是ClassA

的定义
public class ClassA
{
    public int first;
    public int second;
    public bool Equals(ClassA other)
    {
        if (other == null) return false;
        return first == other.first &&
            second == other.second;
    }
}

现在让我们说我们有这些对象:

ClassA a = new ClassA() { first = 1, second = 2 };
ClassB b = new ClassB() { first = 1, second = 2, third = 3 };

此处a.Equals(b)将为true。它具有两个要检查的属性,因此它认为它们是相同的。你希望这些对象被认为是平等的吗?

另一种实现方式是:

public bool Equals(ClassA other)
{
    if (other == null) return false;
    if (other.GetType() != typeof(ClassA)) return false;
    return first == other.first &&
        second == other.second;
}

这里我们明确地检查(在运行时授予,而不是在编译时),以确保另一个实例不是更多派生类型。在这种情况下,a.Equals(b)将是错误的。您可以实现自己喜欢的任何语义。

答案 1 :(得分:1)

Employee继承自Human

Employee包含的属性多于Human,但它仍然是Human

如果您实施Human.Equals(),则可以传递Employee,因为内心深处Employees仍然是Humans ....但您无法对待Humans }例如Employees,因为并非所有Humans都拥有Earnings属性