-1

使用下面的代码。

class Program
{
    static void Main(string[] args)
    {
        BaseClass obj = new BaseClass();
        DerivedClass obj2 = new DerivedClass();

        var x = obj.Method(2);
        var z = obj2.Method(1);
    }
}

class BaseClass
{
    public int Method(int i) { return i; }
}

class DerivedClass : BaseClass
{
    public string Method(int i) { return i.ToString(); }
}

为什么当我在派生类中有方法时,派生类对象正在调用它自己的函数,如果我没有它,派生类对象正在调用基函数?

4

4 回答 4

1

如果要覆盖此行为,则可以使用new 修饰符标记方法,该修饰符将显式隐藏派生类中的成员。

public new string Method(int i) { return i.ToString(); }
于 2013-03-11T08:30:22.267 回答
0

您应该已经收到了来自编译器的警告。您的新Method()方法隐式隐藏了基础(您可以使用new关键字使其显式,这也会使编译器警告静音)。另请参阅http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx

请注意,在 C# 中,不存在仅基于其输出类型重载方法这样的事情。仅仅因为您的新方法恰好返回 astring并不会使其签名与基的签名有任何不同。

请注意以下关于隐藏危险的警告,这也可能有助于说明正在发生的事情:

static void Main(string[] args)
{
    BaseClass obj = new BaseClass();
    DerivedClass obj2 = new DerivedClass();

    var x = obj.Method(2); //returns 2
    var z = obj2.Method(1); //returns 2 (2*2)
    var a = ((BaseClass)obj2).Method(1); //returns 1 (base's implementation!)
}

class BaseClass
{
    public int Method(int i) { return i; }
}

class DerivedClass : BaseClass
{
    public int Method(int i) { return i * 2; }
}

以下代码中的行为不同,后者添加了一个新的Method(string)重载:

static void Main(string[] args)
{
    BaseClass obj = new BaseClass();
    DerivedClass obj2 = new DerivedClass();

    var x = obj.Method(2); //returns 2
    var z = obj2.Method("1"); //returns "1"
    var a = ((BaseClass)obj2).Method("1"); //returns "1"
}

class BaseClass
{
    public int Method(int i) { return i; }
}

class DerivedClass : BaseClass
{
    public string Method(string s) { return s; }
}
于 2013-03-11T08:31:42.657 回答
0

继承意味着您DerivedClass自动拥有所有拥有的成员BaseClass。因此它也有Method哪些返回int

DerivedClass. 因为 thenDerivedClass有两个具有相同签名的方法。这就是您从编译器收到警告的原因。即使当您使用关键字的修饰符时警告消失了,使用new具有相同签名的两个方法仍然是一个坏主意。

相反,请为 中的方法选择一个未使用的名称DerivedClass

更直接地回答你的问题:当你只有一种方法时Method,你在里面写的那个BaseClass,一切都很好。DerivedClass 继承了这个方法。这就是您可以调用它的原因obj2。但是当你在 中引入第二种方法时DerivedClass,调用obj2.Method(1);需要在两种方法之间进行选择,因为不幸的是有两种方法具有相同的签名。这种情况下的规则是选择 中定义的方法DerivedClass。但请注意,这里重要的是编译时类型。所以如果你说

BaseClass obj3 = new DerivedClass();
var w = obj3.Method(42);

即使运行时类型obj3DerivedClass,由于编译时类型,它也是第一个被调用的方法。就像我说的,obj3拥有这两种方法。

于 2013-03-11T08:35:19.577 回答
0

这是因为,您将基方法隐藏在派生类中,并且当您创建派生类的对象时,它将调用自己的实现。当您在没有适当机制的情况下(通过使用 new 关键字)以及当您在派生类中没有该方法时,编译器会大喊大叫,然后基类实现就会启动。

于 2013-03-11T08:35:25.027 回答