从继承子类对象访问父类虚方法

Posted

技术标签:

【中文标题】从继承子类对象访问父类虚方法【英文标题】:Access Parent Class virtual method from inheriting Child Class Object 【发布时间】:2013-01-25 04:26:19 【问题描述】:

我想知道是否可以使用继承类(覆盖方法)对象访问基本虚拟方法。

我知道这不是一个好的做法,但我想知道这在技术上是否可行。我不遵循这种做法,只是出于好奇。

我确实看到了一些类似的问题,但我没有得到我正在寻找的答案。

例子:

public class Parent

    public virtual void Print()
    
        Console.WriteLine("Print in Parent");
    


public class Child : Parent

    public override void Print()
    
        Console.WriteLine("Print in Child");
    


class Program

    static void Main(string[] args)
    
         Child c = new Child();
         //or Parent child = new Child(); 
         child.Print();  //Calls Child class method
         ((Parent)c).Print(); //Want Parent class method call
    

【问题讨论】:

我昨天在这里回答了几乎相同的问题; ***.com/questions/14491513/… 显式调用父类 Print() 方法。显然,正如您所指出的,这种架构试图逆转多态行为——不明智 @AdityaSihag;这不适用于被覆盖的方法。只有new,根据上面的链接。 @RJLohan 你是绝对正确的。我认为我不明白 OP 的目的是什么,我已经删除了我的答案。 Use reflection to invoke an overridden base method的可能重复 【参考方案1】:

根据我评论的链接副本,您可以使用一些反射技巧来做到这一点:

static void Main(string[] args)

    Child child = new Child();
    Action parentPrint = (Action)Activator.CreateInstance(typeof(Action), child, typeof(Parent).GetMethod("Print").MethodHandle.GetFunctionPointer());

    parentPrint.Invoke();

【讨论】:

【参考方案2】:

不 - 不能调用基类的 Virtual 方法 - 在这种情况下调用该方法的最派生实现。在您给出的示例中,在这两种情况下都会打印"Print in Child"

【讨论】:

不是真的!在派生类中使用 NEW 关键字创建具有相同签名的方法是隐藏或隐藏基类中的方法。这意味着您正在从派生类调用 NEW 方法,而不是从基类调用方法。使您的打印语句具有与派生类的新方法不同的文字,并亲自查看!【参考方案3】:

在我看来,你能做的最好的事情是:

public class Parent

    public virtual void Print()
    
        Console.WriteLine("Print in Parent");
    


public class Child : Parent

    public override void Print()
    
        base.Print();
        Console.WriteLine("Print in Child");
    


class Program

    static void Main(string[] args)
    
         Child c = new Child();
         //or Parent child = new Child(); 
         child.Print();  //Calls Child class method
         ((Parent)c).Print(); //Want Parent class method call
    

【讨论】:

【参考方案4】:

我不知道这什么时候会有帮助。但是一个体面的解决方法可能是重载或编写一个只调用父类的虚拟方法。它看起来像这样:

public class Child : Parent

    public void Print(bool onlyCallFather)
    
    if(onlyCallFather)
        base.Print();
    else
        Print();
    

然后在你的主要方法中:

class Program

    static void Main(string[] args)
    
         Child c = new Child();
         child.Print(false);  //Calls Child class method
         child.Print(true);  //Calls only the one at father
    

所以它会做你想做的事。我实际上已经看到过这种解决方法来判断您是否希望调用基本方法。

【讨论】:

以上是关于从继承子类对象访问父类虚方法的主要内容,如果未能解决你的问题,请参考以下文章

vc 父类实现一个虚函数,子类继承并也实现这个虚函数,子类调用这个虚函数,父类这个虚函数会不会执行?

子类继承父类怎么在父类的方法中访问子类的变量

子类从父类继承过来的方法可以操作子类自己定义的成员变量吗

c++ 虚函数 如何调父类 而非子类

java继承

面向对象三大特征之多态