回答
如果您确实想在子类中使用override
方法,则需要使用virtual
关键字。否则,基础实现将被新实现隐藏,就像您使用关键字new
声明了一样。
通过“覆盖”它们来隐藏方法,而不声明基方法virtual
让您没有多态性,这意味着:如果您向“基本”版本“投射”特定版本并调用方法,则始终基类将会使用实现而不是重写的版本 - 这不是你所期望的。
实施例:
class A
{
public void Show() { Console.WriteLine("A"); }
}
class B : A
{
public void Show() { Console.WriteLine("B"); }
}
A a = new A();
B b = new B();
a.Show(); // "A"
b.Show(); // "B"
A a1 = b;
a1.Show(); // "A"!!!
现在我想我们可以重写方法,即使不使用“虚拟”关键字。
不,你不能。与Java相反,C#成员默认密码为,除非您使用关键字virtual
标记它们,否则不能覆盖它们。
virtual
是一种定义方法具有默认实现的方式,但该实现可能会在子类中被重写。除了使用虚拟外,不能使用new
关键字直接覆盖方法(这通常是不好的做法)。
执行virtual
的一个很好的例子是ToString()
方法。 C#中的每个对象都能保证能够调用ToString()
,因为每个对象都继承自基类System.Object
类,其中包含虚拟方法ToString()
。然而,派生类可以覆盖这个,并提供它们自己的实现,这可能对对象的用户更有用。
更新:我最近写了一篇博客文章,深入到这个主题。 Check it out here。
在这个例子中请看:
void Main()
{
var o1 = new S();
Console.WriteLine(((B)o1).m1());
}
public class B
{
public virtual string m1() {
return "m1";
}
}
public class S : B
{
override public string m1() {
return "overridden m1";
}
}
在这个例子中的子类S
被实例化并分配给对象变量o1
。 在Console.WriteLine
语句的参数中,它被投入到基类B
中,然后调用方法m1
。 因为我们已经在子类S
使用virtual
在基类B
和override
,我们正在
重写M1
作为输出。如果您在子类中删除S
在virtual
的m1
方法声明中B
和override
然后你得到
M1
作为输出,这意味着,中投也有效果的使用基类B
中方法m1
的原始声明。
N.B.如果您使用的子类S
的new
关键字,如
new public string m1() {
return "overridden m1";
}
假设在基类B
的virtual
关键字不存在,你得到的输出
M1
。如果您不会将其转换为B
,则将使用新方法。这叫做遮蔽(或隐藏)一种方法(原始方法的基类)。
摘要:
要覆盖的方法,如果你投的基类,它也应该是有效的,使用在基类的
virtual
关键字和override
在子类。如果您打算重写只应在子类中激活的方法,请在子类方法声明中使用
new
关键字。正如你所看到的,它在没有它的情况下也能正常工作,但如果它在那里会更好,所以大家都知道这是该方法的新版本。
- 1. 在C++中使用虚拟关键字
- 2. 虚拟关键字
- 3. C#虚拟&覆盖关键字
- 4. C中的虚拟键盘#
- 5. “虚拟”是C++中的限定符还是关键字?
- 6. 缺少虚拟关键字的警告
- 7. 如何避免虚拟关键字
- 8. 偏差与虚拟关键字
- 9. 虚拟关键字和库提前
- 10. 虚拟关键字内部组件
- 11. C# - 关键字的使用虚拟+倍率与新
- 12. C++虚拟关键字vs覆盖函数
- 13. 我们可以在c#的方法中同时使用虚拟关键字和新关键字吗?
- 14. 为什么所有关于虚拟关键字的模糊?
- 15. 有关虚拟方法表中的C++
- 16. 虚拟关键字在函数声明中的位置
- 17. JavaScript中的虚拟键盘
- 18. 虚拟键盘
- 19. 从xamarin java绑定中删除虚拟关键字
- 20. 关键字“虚拟”是否传递给中间基类?
- 21. 订购虚拟的,抽象的,覆盖关键字
- 22. 新关键字的真实用法隐藏虚拟方法实现? c#
- 23. C++ 11 =默认关键字虚拟函数指定默认的纯实现
- 24. Android虚拟键盘KeyListener获取虚拟键盘按键
- 25. 显示虚拟关键字asp.net的密码
- 26. 不使用虚拟关键字的多态性
- 27. 虚拟关键字与类声明的用法
- 28. 虚拟关键字与g ++(Ubuntu)的奇怪(?)行为
- 29. C#虚拟键码为@符号
- 30. 虚拟按键在窗口C#
“现在我想我们可以重写方法,即使不使用'虚拟'关键字。”您认为? – BoltClock
@BoltClock当然。基类中的'abstract'和派生类中的'override'就足够了。不需要'虚拟':P – CodesInChaos
是的,虚拟的意思是“我提供了一个实现,但是你可能会多态地覆盖它”,而抽象的意思是“我定义了一些你必须提供的实现,它将以多态的方式运行”。与阴影(通常被认为是次优的)不同,函数签名必须匹配。 –