Overriding
是一个允许您更改子类中方法功能的原则。
对于Ex。
//Overriding
public class test
{
public virtual getStuff(int id)
{
//Get stuff default location
}
}
public class test2 : test
{
public override getStuff(int id)
{
//base.getStuff(id);
//or - Get stuff new location
}
}
当我们在test2中测试类Inherit
时,编译器知道父类中有一个虚方法。
那么为什么方法覆盖是运行时绑定而不是编译时限?
答案 0 :(得分:3)
它是运行时绑定(如果这甚至是正确的措辞 - 我不相信),因为即使使用test2
变量,您实际上也可以拥有:
test2 obj = new test3(); // imagine test3 inherits from test2
obj.getStuff(id);
此处变量是test2
,但对象是test3
。您可能会争辩说,如果它是sealed
等,但实际上甚至非虚拟实例(非静态)方法都会通过callvirt进程。它运作良好,速度非常快。另外,callvirt操作码具有必要的空值检查,这意味着您的代码(在引擎盖下)不必经常检查空值(如果是静态调用则必须这样做)
唯一的例外是struct
s覆盖object
方法;以下是静态调用:
int i = 1;
string s = i.ToString();
答案 1 :(得分:1)
考虑这个片段。
test Create()
{
return new test2();
}
test a = Create();
a.getStuff(0); // which method is called?
编译器无法知道Create
方法的返回值是test2类型。这是明确隐藏的。
您应该从编译器的角度来看这个。鉴于编译器正在将值视为test
类型,它怎么知道调用test2.getStuff
方法?
答案 2 :(得分:1)
class BaseClass
{
public virtual void Test(){
Console.WriteLine("This is test of base class");
}
}
class DerivedClass : BaseClass
{
public override void Test(){
Console.WriteLine("This is test of derived class");
}
}
class DerivedClass1 : BaseClass
{
public override void Test(){
Console.WriteLine("This is test of derived class-1");
}
}
现在使用
BaseClass b = new DerivedClass();
b.Test(); // This will derived class method
假设由另一个方法创建的对象取决于条件,但所有对象都来自BaseClass
public BaseClass GetObject(int i)
{
if(i==1) return new DerivedClass();
if(i==2) return new DerivedClass1();
}
BaseClass b = GetObject(1);
b.Test(); // This will derivedclass method
BaseClass b = GetObject(2);
b.Test(); // This will derivedclass1 method
所以所有事情都取决于i
的值,它可以在运行时和运行时决定依赖于引用的类型b
按照Test方法调用。
答案 3 :(得分:0)
只是为了添加其他答案,编译器在编译时无法弄清楚它在运行时通过发出适当的代码在运行时或通过使用其他技术来实现它。 / p>