【问题标题】:How do I call a super class method from sub class object which has overridden?如何从已覆盖的子类对象中调用超类方法?
【发布时间】:2018-11-01 21:41:10
【问题描述】:

我一直在阅读有关Polymorphism 的信息,并且经历了一些有趣的事情。

我创建了两个类:一个超类和一个派生类。如您所见,派生类继承自超类并使用其方法。

在派生类中,我重写了超类的方法。

所以我的问题是:我想从派生类的对象调用超类方法

例如:

derivedClass a = new derivedClass()
a.method();

我希望a.methood() 执行超类方法。

这可能吗?

【问题讨论】:

  • 如果调用者应该能够调用基类的方法或派生类的方法,那么您首先不应该重写该方法,您应该创建一个全新的方法。跨度>
  • 所以不可能?
  • 这不是一个好主意,不管你能不能做到。
  • 只是我听说过一些“子类引用为超类”,我仍然不知道该怎么做以及他们为什么这样做
  • 那句话的上下文是什么?它提供了任何例子吗?这样做是怎么说的?

标签: c# oop polymorphism


【解决方案1】:

总结你的问题:你有一个基类和一个派生类。派生类覆盖基类的虚方法。给定派生类的实例,是否可以强制调用基类版本的方法,而不是派生类?

简短的回答:在课堂上,是的。在课外,没有。

基本上您希望在这里做的是对虚拟方法的非虚拟调用。对基类方法进行非虚拟调用是合法的,但只能从类内部

class B
{
  public virtual void M() { Console.WriteLine("B.M"); }
}
class D : B
{
  public override void M() { Console.WriteLine("D.M"); }
  public void BM() { base.M(); }
}
...
D d = new D();
d.M(); // D.M
d.BM(); // B.M

现在,对于高级玩家偷偷摸摸的方法来调用B.M 并以D 的实例作为接收者,我不会告诉你它们是什么。 您不应尝试这样做。 CLR 可能会将此类尝试标记为违反其“已验证代码”规则。 虚拟覆盖规则是为了您的方便和安全。不要试图绕过这些规则。

【讨论】:

  • 谢谢这是很酷的方法,如果可以的话,请告诉我什么是后期绑定,我在stackify.com/oop-concept-polymorphism 中找到了它,我不明白这部分“子类引用为超类”为什么你会这样做以及如何在 c# 中这样做
  • @CamiloTerevinto:那是一个愚蠢的错字。感谢收看。
  • @Ezio:“后期绑定”基本上意味着在运行时做出一些关于调用什么代码的决定。虚方法调用是后期绑定的一种形式。请参阅我关于该主题的文章,其中我描述了许多不同形式的后期绑定:ericlippert.com/2012/02/06/what-is-late-binding
  • @Ezio:通过“子类被引用为超类”,作者的意思是你有一个变量Animal a = new Dog(); a.MakeNoise();,结果是吠叫。我们有一个类型为基类Animal 的引用,它引用派生类Dog 的一个实例,并且运行时的行为是后期绑定的:它吠叫。仅考虑到我们有一只动物在发出声音这一事实,在呼叫发生之前我们不知道它是会吠叫还是咆哮。
  • 非常感谢,这对我帮助很大,但我们为什么要这样做,为什么我们要做动物 a = new dog 而我们可以只做 dog a = new dog ()?
【解决方案2】:

从派生类外部这是不可能的。它是在派生类中。

如果您定义了这些类:

class A
{
  public virtual void Method1() { Console.WriteLine("A"); }
}
class B : A
{
  override public void Method1() { Console.WriteLine("B"); }
  public void BaseMethod1() { base.Method1(); }
}

您可以执行以下操作:

  B b = new B();
  b.Method1(); //Outputs "B"
  b.BaseMethod1(); //Outputs "A"
  ((A)b).Method1(); //***Outputs "B" (even though you cast it as A)

如果将overide 更改为new,则最后一行的输出为“A”

【讨论】:

  • 该问题特别提到该方法被覆盖。您的示例不涉及覆盖该方法。
【解决方案3】:

你可以根据自己的需求尝试调用base方法,如果有条件,根据你要调用的条件,你也可以使用那个条件。

public class SubClass : SuperClass
{
    public bool IsCallBaseClassMethod { get; set; }

    public override void Method(){
        if (IsCallBaseClassMethod)
        {
            base.Method();
        }
    }
}

根据您对对象的要求设置条件,并为同一对象调用方法。

SubClass testObject = new SubClass();
testObject.IsCallBaseClassMethod  = true;
testObject.Method();

【讨论】:

    猜你喜欢
    • 2020-02-15
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2019-12-09
    • 2020-05-03
    • 2017-08-27
    • 2023-04-11
    • 2014-05-11
    相关资源
    最近更新 更多