如何使用基类对象调用派生函数

本文关键字:派生 函数 调用 对象 何使用 基类 | 更新日期: 2023-09-27 18:05:51

class Parent
{
    public int GetNo()
    {
        return 1;
    }
}
class Child : Parent
{        
    public Child()
    {
    }
    public int GetNo()
    {                       
        return 2;
    }
}
Parent p = new Child();
p.GetNo();

但是它调用Base.GetNo()。我知道如果我在碱中使用虚,它会叫Child.GetNo()但是我不能在Base中使用虚拟,因为我必须从已经分布在DLL中的Base中派生我的类。因此,我无法修改基类的现有函数。

任何建议都是宝贵的。由于

如何使用基类对象调用派生函数

可以强制转换:

((Child)p).GetNo();

if(p is Child)
    (p as Child).GetNo();

我刚刚来到这里,所以我可以找到一个不使用强制转换的解决方案,但因为我没有找到它,这里是一个。

也许它可以帮助别人。

abstract class Parent
{
    public int GetNo()
    {
        return GetNoImpl();
    }
    protected abstract int GetNoImpl();
}
class Child : Parent
{        
    public Child()
    {
    }
    protected override int GetNoImpl();
    {                       
        return 2;
    }
}
Parent p = new Child();
p.GetNo();

你可以强制使用显式强制转换,例如

((Child)p).GetNo();

或者你可以使用隐藏,例如

public new int GetNo()
{
  return 2;
}

虽然我认为后者只有在变量类型为隐藏方法的类时才会被调用。

如果你真的需要正确地覆盖一个方法,并且它来自编译的DLL,请考虑与开发人员联系,看看他们是否可以使该方法虚拟(如果不是为什么),或者如果一个开源项目只是获得源代码并自己修改它。

如果没有在方法上声明virtual,则基方法将始终被调用,因为您将变量声明为Parent。如果不能将virtual附加到基类,那么只能将变量声明为Child,或者将其强制转换为Child并调用GetNo方法:

Child p = new Child();
p.GetNo();

或:

Parent p = new Child();
((Child)p).GetNo();