为什么方法重写是运行时绑定的
本文关键字:绑定 运行时 方法 重写 为什么 | 更新日期: 2023-09-27 17:58:08
Overriding
是一个允许您更改子类中方法功能的原则。
例如
//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
测试类时,编译器知道父类中有一个虚拟方法。那么,为什么方法重写是运行时绑定的而不是编译时绑定的呢?
它是运行时绑定(如果这是正确的措辞——我不相信),因为即使有test2
变量,你实际上也可以有:
test2 obj = new test3(); // imagine test3 inherits from test2
obj.getStuff(id);
这里的变量是test2
,但对象是test3
。您可能会争辩说,如果是sealed
等,但实际上即使是非虚拟实例(非静态)方法也要经过callvirt过程。它运行良好,速度非常快。此外,callvirt操作码有必要的null检查,这意味着你的代码不必(在引擎盖下)不断地检查null(如果是静态调用,这是必要的)
这里唯一的例外是覆盖object
方法的struct
;以下是静态调用:
int i = 1;
string s = i.ToString();
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 Create()
{
return new test2();
}
test a = Create();
a.getStuff(0); // which method is called?
编译器无法知道Create
方法的返回值是test2类型。它是明确隐藏的。
您应该从编译器的角度来看待这个问题。假设编译器将该值视为test
类型,那么它怎么知道调用test2.getStuff
方法呢?
只需添加到其他答案中,编译器在编译时无法解决的任何问题,都可以通过在运行时发出适当的代码或使用其他技术来实现。