使用派生参数覆盖函数

时间:2016-08-01 09:55:16

标签: c# inheritance

我希望将数组中派生类的数量作为基类。 然后遍历数组并让派生类调用一个接收相同DB的函数,但每个派生类应该将DB作为不同的接口接收。

有没有其他方法可以实现这种情况?

那是我尝试做的,但覆盖无法找到合适的虚函数:

public interface IBase
{

}
public interface IClass1 : IBase
{
    bool[] IsEnable { get; }
}

public interface IClass2 : IBase
{
    bool[] IsEnable { set; }
}

public class DB : IBase, IClass1, IClass2
{
    public bool[] IsEnable { get; set; }
}

public abstract class Base
{
    public virtual void fRun(IBase p_oOb)
    {

    }
}

class MyClass1 : Base
{
    public override void fRun(IClass1 p_oOb)
    {
        Console.WriteLine("MyClass1 fRun.");
    }
}

class MyClass2 : Base
{
    public override void fRun(IClass2 p_oOb)
    {
        Console.WriteLine("MyClass2 fRun.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        DB db = new DB();
        Base[] classes = new Base[] {new MyClass1(), new MyClass2()};
        foreach (var Class in classes)
        {
            Class.fRun(db);
        }   
    }
}

3 个答案:

答案 0 :(得分:0)

此代码无法编译:

class MyClass1 : Base
{
    public override void fRun(IClass1 p_oOb)
    {
        Console.WriteLine("MyClass1 fRun.");
    }
}

它抛出:

  

MyClass1.fRun(IClass1)没有合适的方法来覆盖

您不能覆盖实际上与基类中的函数不同的基类函数。

  • 如果IClass1IClass2派生自IBase(原样),那么 拥有IBase的签名并传递派生。
  • 如果它们不总是派生,如果它们具有不同的功能,您希望在具体类型中执行,或者如果您希望特定类接收特定的IBase,则将其设为通用,fRun将获得{TBase 1}}。在这种情况下,您可能还需要一些额外的抽象来将正确的IBase传递给每个Base

根据选项1修复代码,它将是:(另请注意,IsEnable现在位于IBase

public interface IBase
{
    bool[] IsEnable { get; }
}
public interface IClass1 : IBase { }

public interface IClass2 : IBase { }

public class DB : IBase
{
    public bool[] IsEnable { get; set; }
}

public abstract class Base
{
    public virtual void fRun(IBase p_oOb) { }
}

class MyClass1 : Base
{
    public override void fRun(IBase p_oOb)
    {
        Console.WriteLine("MyClass1 fRun.");
    }
}

class MyClass2 : Base
{
    public override void fRun(IBase p_oOb)
    {
        Console.WriteLine("MyClass2 fRun.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        DB db = new DB();
        Base[] classes = new Base[] { new MyClass1(), new MyClass2() };
        foreach (var Class in classes)
        {
            Class.fRun(db);
        }
    }
}

答案 1 :(得分:0)

MyClass1MyClass2中的覆盖分别需要如下所示:

public override void fRun(IBase p_oOb)
{

}

否则它不会覆盖初始虚拟方法。

您可以使用overriden方法在每个类中调用私有方法:

public override void fRun(IBase p_oOb)
{
    if(p_oOb is IMyClass1) // or IMyClass2 respectively
        private_fRun(p_oOb);
}

顺便说一下。如果您不打算在abstact基类中实现任何内容,则应该使用abstract - 方法上的关键字。这样,您的派生类就需要实现它。

此外,您的课程仅从Base继承。他们是否还应该实现接口IClass1IClass2。只是出于好奇。

答案 2 :(得分:0)

您应该使用:

class C
{
    private MyClass1 _1 = new MyClass1();
    private MyClass2 _2 = new MyClass2();

    public void fRun(IClass1 p_oOb1, IClass2 p_oOb2)
    {
        _1.fRun(p_oOb1);
        _2.fRun(p_oOb2);
    }
}

班级C不会继承Base,因为:

fRun(IBase p_oOb)

与以下不同:

fRun(IClass1 p_oOb1, IClass2 p_oOb2)

如果确实继承了它,编译器会抛出错误。