用派生参数重写函数

本文关键字:函数 重写 参数 派生 | 更新日期: 2023-09-27 17:59:31

我想在数组中保留一定数量的派生类作为它们的基类。然后在数组上循环,让派生类调用一个函数,该函数接收相同的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);
        }   
    }
}

用派生参数重写函数

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);
}

Btw。如果您不打算在abstract基类中实现任何内容,那么应该在方法上使用abstract-关键字。这样,就需要派生类来实现它

此外,您的类仅继承自Base。它们是否也应该实现接口IClass1IClass2。只是出于好奇。

此代码不会编译:

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

它抛出:

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

不能重写基类函数,因为它实际上与基类中的函数不同。

  • 如果IClass1IClass2是从IBase导出的(照原样),那么使用CCD_ 10进行签名并传递派生的
  • 如果它们不总是派生的,如果它们有不同的函数,你想在具体类型中执行,或者如果你想让特定的类接收特定的IBase,那么就把它设为泛型,fRun就会得到一个TBase。在这种情况下,您可能还需要一些额外的抽象来将正确的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);
        }
    }
}

您可能应该使用:

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)

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