Jim*_*hel 45
阴影隐藏基类中的方法.使用您链接的问题中的示例:
class A
{
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A
{
public new int Foo() { return 1;}
public override int Bar() {return 1;}
}
Run Code Online (Sandbox Code Playgroud)
类B 会覆盖虚方法Bar.它隐藏(阴影)非虚方法Foo.覆盖使用override关键字.阴影是使用new关键字完成的.
在上面的代码中,如果在类中定义方法时没有使用new关键字,则会收到此编译器警告:FooB
'test.B.Foo()' hides inherited member 'test.A.Foo()'. Use the new keyword if hiding was intended.
Run Code Online (Sandbox Code Playgroud)
mqp*_*mqp 21
假设我有一个实现虚方法的基类:
public class A
{
public virtual void M() { Console.WriteLine("In A.M()."); }
}
Run Code Online (Sandbox Code Playgroud)
我还有一个派生类,它也定义了一个方法M:
public class B : A
{
// could be either "new" or "override", "new" is default
public void M() { Console.WriteLine("In B.M()."); }
}
Run Code Online (Sandbox Code Playgroud)
现在,假设我写了一个这样的程序:
A alpha = new B(); // it's really a B but I cast it to an A
alpha.M();
Run Code Online (Sandbox Code Playgroud)
对于我希望如何实现,我有两种不同的选择.默认行为是调用A的M版本.(这与将" new"关键字应用于的行为相同B.M().)
当我们有一个具有相同名称但从基类调用时具有不同行为的方法时,这称为"阴影".
或者,我们可以指定" override" B.M().在这种情况下,alpha.M()会调用B的版本M.
Jor*_*oba 10
阴影包括在子类中隐藏具有新定义的基类方法.
隐藏和覆盖之间的区别与调用方法的方式有关.
这样,当重写虚方法时,基类的方法调用表的调用地址将替换为子例程的地址.
另一方面,当隐藏方法时,会将新地址添加到子类的方法调用表中.
当调用相关方法时:
如果我们通过引用子类来调用该方法,那么行为是相同的,如果方法已被重写,则方法地址将在基类中找到,如果方法被隐藏,则方法地址将在子类,并且由于已经找到,因此不会搜索基类表.
如果我们通过引用基类来调用该方法,那么行为会发生变化.覆盖时,当方法地址覆盖基类条目时,即使持有对基类的引用,我们也会调用子方法.使用阴影时,基类方法表(它是我们持有对基类的引用时唯一可见的)包含虚方法地址,因此将调用基类方法.
通常,阴影是一个坏主意,因为它会根据我们对它的引用引入实例行为的差异.
| 归档时间: |
|
| 查看次数: |
56812 次 |
| 最近记录: |