CLR调用一个类型的实例方法时会先判断这个方式是否是可被重写的虚方法,如果只是普通方法,那就直接调用,如果是虚方法,那就在继承链上查找实际类型的最终重写版本。复现一下这个过程,调用类型A的show()方法,先查找是否是虚方法,
第一种情况不是虚方法,那么直接调用A的show()方法
第二种情况发现了A的show方法是virtual,可重写的,那么就在继承链上找到A的实际类型C的该方法最终重写版本,也就是B重写的Show()方法。
第一种情况不是虚方法,那么直接调用A的show()方法
第二种情况发现了A的show方法是virtual,可重写的,那么就在继承链上找到A的实际类型C的该方法最终重写版本,也就是B重写的Show()方法。
解决方案 »
- 结果为什么为一个莫名其妙的负数?
- 如何用一个脚本禁用另一个脚本?
- 为什么拉动滚动条,菜单栏也会跟着动?
- 在WinForm中如何给DataGridView高效着色?
- oracle游标超过最大数(仅仅是查询操作)
- WebService 异步调用开始以后怎样响应用户干预的结束?
- 请问在使用C#.net编写的TcpIp通讯程序中,Server端如何检测到Client端已把网线拔了?
- winform radiobutton
- 关于MDI窗体、导航菜单、SplitContainer控件一起使用出现的问题
- DataGrid问题(再现等候)
- wcf TCP error code 10060 错误 但是WcfTestClient连接正常
- Windows API 取另一程序文本框值的问题
class A
{
int X;
}
作为OO语言的一种设计准则,如果你不明确它是公开的,编译器倾向视作它是私有的。比如int X,虽然X没有加上任何修饰,但是它实际上是private而不是public的。这段代码等价
class A
{
private X;
}
那么我们看如下代码
class A
{
public void Foo() { ... }
}
我们没有加上任何关于它是否能够重写的修饰,那么编译器绝对不允许它被重写
它等价
class A
{
public sealed void foo() { ... }
}
如果我们需要让X对外可见,我们必须写
public int X;
一样的道理,如果我们要让foo()可以被重写,我们必须写
public virtual void foo() { ... }
我们看下什么是new。
我们看一个极端的例子:
class A
{
private int X;
public void foo()
{
int X = 1;
this.X = 2;
}
}
我们故意定义了一个和成员变量X一样的局部变量X,那么我们需要一种机制确保它们都可以访问到,但是你要知道,这两个X完全没有一毛钱的关系。
类似的
class A
{
public void foo() { ... }
}
class B
{
public void foo() { ... }
}
此时A.foo()和B.foo()也没有一毛钱的关系,这个能理解么?
那么如果是
class B : A
{
public void foo() { ... }
}
呢?
仍然没有一毛钱的关系。
但是此时B拥有了两个没有一毛钱关系的foo()方法, 一个是自身定义的,一个是从A继承来的。
而new其实就是解决这种冲突的一种机制。
b.foo()表示B的那个
(b as A).foo()表示A的那个
就好比前面的代码中两个X变量也毫无关系一样。现在你应该理解,new和virtual根本风马牛不相及。可是被脑残的部分天朝教师硬是扯在一起讲。