2016-08-01 82 views
0

我想将数组中的派生类作为其基类。 然后在数组上循环并让派生类调用一个接收相同数据库的函数,但每个派生类都应该将该数据库作为不同的接口接收。使用派生参数覆盖函数

有没有另一种方法来实现这种情况?

这就是我试图这样做,但覆盖无法找到合适的虚函数:

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

为什么你不能在被重写的物体内强制使用'IBase'作为所需的接口? – slawekwin

+0

我可以做到这一点..但在这种情况下,myClassx拥有整个数据库的权限,并取决于它自己的权限/可访问性。 –

+0

只要'IClassx'继承自'IBase',是不是这样?也许创建另一个假接口只是为了争取参数的基础。 – slawekwin

回答

0

此代码不能编译:

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

它抛出:

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

您无法重写实际上与基类中的函数不同的基类函数。

  • 如果IClass1IClass2IBase派生(因为它们是),那么只是 具有与IBase签名和传递的。
  • 如果他们不总是派生,如果他们有不同的功能,你想要在具体的类型执行,或者如果你想特定的类接收特定的IBase然后使其通用和fRun将得到TBase。在这种情况下,你也可能会需要一些额外的抽象根据选项1,它会被正确IBase传递给每Base

修复代码:(也注意到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); 
     } 
    } 
} 
0

您在覆盖的MyClass1MyClass2分别需要这个样子:

public override void fRun(IBase p_oOb) 
{ 

} 

否则它不会覆盖最初的虚拟方法。顺便说一句

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

您可以使用覆盖方法调用私有方法在每类。如果您不打算在abstact基类中实现任何内容,则应该在该方法上使用abstract - 关键字。这样,你的派生类就必须实现它。

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

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) 

如果它没有继承它的编译器会抛出一个错误。