C#从基类隐藏,覆盖和调用函数

时间:2010-03-23 12:36:40

标签: c# inheritance override base member-hiding

我正在学习C#,我遇到了以下问题。我有两个类:base和derived:

class MyBase
{
    public void MyMethod()
    {
        Console.WriteLine("MyBase::MyMethod()");
    }
}


class MyDerived: MyBase
{
    public void MyMethod()
    {
        Console.WriteLine("MyDerived::MyMethod()");
    }
}

目前,没有virtualoverride关键字。当我编译它时,我得到警告(当然是预期的),我试图隐藏MyMethodMyBase

我想要做的是从具有派生类实例的基类调用该方法。我是这样做的:

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()         |

我希望你的表格清楚。 我有两个问题

  1. 从基类(((MyBase)myDerived).MyMethod();)调用函数是否正确?我知道base关键字,但只能从派生类的内部调用它。是不是?
  2. 为什么在最后一种情况下(使用virtualoverride修饰符)调用的方法来自派生类?你能解释一下吗?

4 个答案:

答案 0 :(得分:18)

当您在覆盖该方法的类型实例上调用virtual方法时,即使您转换为基类,也会始终调用被覆盖的版本。

在覆盖该方法的类上调用虚方法的基本实现的唯一方法是在使用base关键字调用该方法的派生类(而不是基类)中创建第二个方法

一般来说,需要这样做是API设计不佳的标志 - 如果您认为需要调用基本版本,派生版本可能应该有不同的名称。

答案 1 :(得分:3)

至于你的第二个问题,你不是要改变你引用的对象的类型,而是改变你引用它的接口。因此,如果你有一个继承自A并覆盖函数C的对象B,即使你将B称为A,它仍然会调用派生类型最多的实现,在本例中为B.

答案 2 :(得分:2)

你是对的 - base只能在派生类中调用 - Source

此页面还提供了如何覆盖基类定义的示例。

答案 3 :(得分:2)

  1. 你说得对,base指的是给定实例的基类。
  2. 所涉及的机制称为多态:你应该在没有警告的情况下更好地工作。面向自然物体的好方法是你提到的最后一种情况。
  3. 顺便说一句,尽量避免编写强制执行替换原则的代码,换句话说,不要编写依赖于类层次结构实现的代码,因为如果添加新代码,则必须修改此代码派生类到你的基类。