2016-08-01 11 views
0

Ich möchte Anzahl der abgeleiteten Klassen in einem Array als ihre Basisklasse halten. Dann Schleife über das Array und lassen Sie die abgeleiteten Klassen eine Funktion aufrufen, die den gleichen DB erhalten, aber jede abgeleitete Klasse sollte den DB als eine andere Schnittstelle erhalten.Override-Funktion mit einem abgeleiteten Argument

Gibt es eine andere Möglichkeit, einen solchen Fall zu implementieren?

Das, was ich zu tun versucht, aber die Überschreibung kann nicht finden, eine geeignete virtuelle Funktion: kompilieren

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

Warum können Sie 'IBase' nicht als gewünschte Schnittstelle innerhalb von überschriebenen Körpern darstellen? – slawekwin

+0

kann ich das tun .. aber in diesem Fall hat myClassx die Berechtigung für die gesamte DB und es liegt daran, eine eigene Erlaubnis/Zugänglichkeit zu senken. –

+0

Ist das nicht der Fall, solange 'IClassx' von' IBase' erbt? Vielleicht erstellen Sie eine andere, gefälschte Schnittstelle, nur um eine Basis für das Argument zu haben. – slawekwin

Antwort

0

Dieser Code wird nicht:

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

Es wirft:

MyClass1.fRun (IClass1) Keine geeignete Methode zum Übersteuern

Sie können eine Basisklassenfunktion, die sich tatsächlich von der Funktion in der Basisklasse unterscheidet, nicht überschreiben.

  • Wenn IClass1 leiten IClass2 von IBase (wie sie sind), dann nur die Signatur mit dem IBase haben und passieren eine abgeleitet.
  • Wenn sie nicht immer abgeleitet werden, wenn sie verschiedene Funktionen haben, die Sie im konkreten Typ ausführen möchten oder wenn Sie möchten, dass bestimmte Klassen spezifische IBase erhalten, dann machen Sie es generisch und fRun erhalten Sie eine TBase. In diesem Fall müssen Sie auch wahrscheinlich einige zusätzliche Abstraktion die richtigen IBase zu jedem Base

Fixing Code gemäß Option 1 es würde weitergeben müssen: (beachten Sie auch, dass die IsEnable jetzt in IBase ist)

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

Ihre Überschreibung in der MyClass1 und MyClass2 jeweils wie folgt aussehen muss:

public override void fRun(IBase p_oOb) 
{ 

} 

Andernfalls wird die anfängliche virtuelle Methode nicht überschrieben.

können Sie die überschriebene Methode verwenden, um eine private Methode in jeder Klasse zu nennen:

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

Btw. Sie sollten abstract -Keyword für die Methode verwenden, wenn Sie nichts in der Abstact-Basisklasse implementieren möchten. Auf diese Weise müssen Ihre abgeleiteten Klassen es implementieren.

Auch erben Ihre Klassen nur von Base. Sollten sie nicht auch die Schnittstellen IClass1 und IClass2 implementieren. Nur aus Neugier.

0

Sie sollten wahrscheinlich verwenden:

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

Klasse C nicht Base nicht erben, weil:

fRun(IBase p_oOb) 

unterscheidet sich von:

fRun(IClass1 p_oOb1, IClass2 p_oOb2) 

Wenn es geerbt hat, die Compiler würde einen Fehler werfen.