使用以下代码。
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(); }
}
为什么当我在派生类中使用该方法时,派生类对象正在调用它自己的函数,如果我没有它,派生类对象是否正在调用基函数?
答案 0 :(得分:1)
如果要覆盖此行为,则可以使用new modifier标记一个方法,该方法将明确隐藏您派生自的类中的成员。
public new string Method(int i) { return i.ToString(); }
答案 1 :(得分:0)
您应该收到编译器关于此的警告。您的新Method()
方法隐式隐藏基础(您可以使用new
关键字将其显式化,这也会使编译器警告静音)。另请参阅http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx。
请注意,在C#中,没有基于其输出类型重载方法的事情。仅仅因为你的新方法碰巧返回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 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; }
}
答案 2 :(得分:0)
继承意味着您的DerivedClass
会自动拥有BaseClass
拥有的所有成员。因此,它还有Method
,返回int
。
在DerivedClass
中引入一个具有相同名称和相同参数的新方法是个坏主意。因为DerivedClass
有两个具有相同签名的方法。这就是你从编译器收到警告的原因。即使使用new
关键字的修饰符时警告消失,使用两个具有相同签名的方法仍然是个坏主意。
相反,为DerivedClass
中的方法选择未使用的名称。
更直接地回答您的问题:当您只有一个方法Method
时,您在BaseClass
内编写的方法一切都很好。 DerivedClass
继承此方法。这就是你可以在obj2
上调用它的原因。但是当你在DerivedClass
中引入第二种方法时,调用obj2.Method(1);
需要在两种方法之间进行选择,因为不幸的是,有两种方法具有相同的签名。这种情况下的规则是选择DerivedClass
中定义的方法。但请注意,这是编译时类型。所以如果你说
BaseClass obj3 = new DerivedClass();
var w = obj3.Method(42);
即使运行时类型obj3
为DerivedClass
,它也是第一个因编译时类型而被调用的方法。就像我说的那样,obj3
拥有两种方法。
答案 3 :(得分:0)
这是因为,您在派生类中隐藏了基本方法,并且在创建派生类的对象时,它将调用自己的实现。当你没有适当的机制(通过使用new关键字)时,编译器会大声喊叫,当你在派生类中没有方法时,基类实现就会启动。