【问题标题】:Inheritance in C# - override and virtualC# 中的继承 - 覆盖和虚拟
【发布时间】:2018-07-26 17:15:24
【问题描述】:

我是 C# 覆盖和虚拟的新手。在下面的示例中,我想从 A 类中的 Caller 方法调用 B 类中的 Callee 方法。 B 继承 A。有什么想法吗?

namespace Blah
{
    public class Program
    {
        public static void Main(string[] args)
        {
            A a = new A();
            a.Caller();
        }
    }

    class A
    {
        public void Caller()
        {
            Console.WriteLine("In Caller");
            Callee(); // How to make this call B:Callee() and make it print "in B"
        }

        public virtual void Callee()
        {
            Console.Write("In A");
        }
    }

    class B : A
    {
        public override void Callee()
        {
            Console.Write("In B");
        }
    }
}

【问题讨论】:

    标签: c# overriding virtual


    【解决方案1】:

    在您的示例中,您有一个基类A 和一个子类B,它覆盖了A 中的一个方法。这意味着您创建一个替代 A,它可以作为 A 进行交互,但可能具有不同的行为。

    然而,这并不意味着A 的每个实例都会突然开始使用这个定义。在您的示例中,您创建了A 的硬实例,但由于覆盖方法在B 中,因此它永远不会被调用。

    相反,您应该创建B 的实例,您可以将其强制转换为A。允许您的代码将其视为A 对象,即使它的B 也是如此。

    在您的示例中,您唯一需要做的就是创建B (fiddle) 的实例:

        A a = new B();
        a.Caller(); 
        // Prints:
        //   In Caller
        //   In B
    

    其工作方式与 Java 继承大致相同,只是在 C# 中,您需要将方法标记为 virtual 才能覆盖它们。


    但是,如果您的意图是在 A 中更改 Callee 的定义而不必创建 B(因此 new A().Caller() 将打印出“In B”),您应该重新考虑您要尝试的任何内容做。它与虚拟方法完全不同,在大多数情况下您应该尽量避免。

    【讨论】:

      【解决方案2】:

      如果你想在B类中调用Callee方法,你首先要创建这个类的一个实例,然后调用这个方法:

      var b = new B();
      B.Callee();
      

      如果这是您正在寻找的(尽管从实际角度来看没有意义),您应该将上述两行放在类 A 中的方法 Caller 中。

      通常我们定义一个基类,如果我们认为我们定义的类中的方法可以从派生自我们类的类中重新实现,我们将该方法标记为虚拟。当我们从我们的基类派生一个类并且我们不覆盖虚拟方法时,就会调用在基类中定义的方法。而当我们覆盖了基类中定义的虚方法时,派生类中的方法就会被调用。

      【讨论】:

        猜你喜欢
        • 2015-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 2016-03-26
        • 2011-01-08
        相关资源
        最近更新 更多