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

发布于 2024-08-26 09:14:43 字数 1349 浏览 9 评论 0 原文

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

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


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

目前,没有 virtualoverride 关键字。当我编译这个时,我收到警告(这当然是预期的),我试图从 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()         |

我希望您能清楚该表。 我有两个问题

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

I'm learning C# and I encountered the following problem. I have two classes: base and derived:

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


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

For now, without virtual and override key words. When I compile this I get the warning (which is of course expected) that I try to hide MyMethod from MyBase class.

What I want to do is to call the method from the base class having an instance of derived class. I do this like this:

MyDerived myDerived = new MyDerived();
((MyBase)myDerived).MyMethod();

It works fine when I do not specify any virtual, etc. keywords in the methods. I tried to put combination of the keywords and I got the following results:

| MyBase::MyMethod | MyDerived::MyMethod | Result printed on the console |
| -----------------|---------------------|-------------------------------|
| -                | -                   | MyBase::MyMethod()            |
| -                | new                 | MyBase::MyMethod()            |
| virtual          | new                 | MyBase::MyMethod()            |
| virtual          | override            | MyDerived::MyMethod()         |

I hope the table is clear to you. I have two questions:

  1. Is it the correct way to call the function from the base class (((MyBase)myDerived).MyMethod();)? I know about base keyword, but it can be called only from the inside of the derived class. Is it right?
  2. Why in the last case (with virtual and override modifiers) the method which was called came from the derived class? Would you please explain that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷情 2024-09-02 09:14:43

当您在重写该方法的类型实例上调用虚拟方法时,即使您强制转换为基类,也将始终调用重写的版本。

在重写该方法的类上调用虚拟方法的基实现的唯一方法是在派生类(而不是基类)中创建使用 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.

想你的星星会说话 2024-09-02 09:14:43

你是对的 - 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.

我是有多爱你 2024-09-02 09:14:43

至于你的第二个问题,你没有改变你所引用的对象的类型,只是改变你引用它的接口。因此,如果您有一个继承自 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.

手长情犹 2024-09-02 09:14:43
  1. 你是对的,base 指的是给定实例的基类。
  2. 所涉及的机制称为多态性:您应该在没有警告的情况下更好地工作。自然的面向对象的好方法是您提到的最后一种情况。

顺便说一句,尽量避免编写强制替换原则的代码,换句话说,不要编写依赖于类层次结构的实现的代码,因为如果您添加新的派生类,则必须修改此代码你的基类。

  1. You're right, base refers to the base class for a given instance.
  2. The involved mechanism is called polymorphism : you should better work without warning. The natural object oriented good way is the last of the cases you mentioned.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文