C# 隐藏、覆盖和调用基类函数
我正在学习C#,遇到了以下问题。我有两个类:基类和派生类:
class MyBase
{
public void MyMethod()
{
Console.WriteLine("MyBase::MyMethod()");
}
}
class MyDerived: MyBase
{
public void MyMethod()
{
Console.WriteLine("MyDerived::MyMethod()");
}
}
目前,没有 virtual
和 override
关键字。当我编译这个时,我收到警告(这当然是预期的),我试图从 MyBase
类中隐藏 MyMethod
。
我想要做的是从具有派生类实例的基类调用方法。我这样做是这样的:
MyDerived myDerived = new MyDerived();
((MyBase)myDerived).MyMethod();
当我在方法中没有指定任何virtual
等关键字时,它工作得很好。我尝试组合关键字,得到以下结果:
| MyBase::MyMethod | MyDerived::MyMethod | Result printed on the console |
| -----------------|---------------------|-------------------------------|
| - | - | MyBase::MyMethod() |
| - | new | MyBase::MyMethod() |
| virtual | new | MyBase::MyMethod() |
| virtual | override | MyDerived::MyMethod() |
我希望您能清楚该表。 我有两个问题:
- 从基类 (
((MyBase)myDerived).MyMethod();
) 调用函数的正确方法是吗?我知道base
关键字,但它只能从派生类内部调用。对吗? - 为什么在最后一种情况(使用 virtual 和 override 修饰符)调用的方法来自派生类?请您解释一下好吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您在重写该方法的类型实例上调用虚拟方法时,即使您强制转换为基类,也将始终调用重写的版本。
在重写该方法的类上调用虚拟方法的基实现的唯一方法是在派生类(而不是基类)中创建使用
base
关键字调用该方法的第二个方法。一般来说,需要这样做是 API 设计不佳的标志 - 如果您认为需要调用基本版本,则派生版本可能应该有不同的名称。
When you call a
virtual
method on an instance of a type that overrides the method, the overridden version will always be called, even if you cast to the base class.The only way to call the base implementation of a virtual method on a class that overrides the method is to make a second method in the derived class (not the base class) that calls the method using the
base
keyword.In general, needing to do this is a sign of a poor API design - if you think you'll need to call the base version, the derived version should probably have a different name.
你是对的 -
base
只能从派生类中调用 - 来源。本页还提供了如何覆盖基类定义的示例。
You're correct -
base
can only be called from within the derived class - Source.This page also gives an example of how to override the base class definition.
至于你的第二个问题,你没有改变你所引用的对象的类型,只是改变你引用它的接口。因此,如果您有一个继承自 A 并重写函数 C 的对象 B,即使您将 B 引用为 A,它仍然会调用最派生类型(在本例中为 B)的实现。
As for your second question, you are not changing the type of the object you have a reference to, just the interface you are referencing it through. So if you have an object B that inherits from A and overrides function C, even if you refer to B as an A, it still calls the implementations of the most derived type, in this case B.
base
指的是给定实例的基类。顺便说一句,尽量避免编写强制替换原则的代码,换句话说,不要编写依赖于类层次结构的实现的代码,因为如果您添加新的派生类,则必须修改此代码你的基类。
base
refers to the base class for a given instance.By the way, try to avoid writing code that enforces the substitution principle, in other word, don't write code that depends on the implementation of your class hierarchy because you'll have to modify this code if you add a new derived class to your base class.