2009-06-26 4 views
4

Ich schreibe Schnittstellen für neues Projekt und möchte einen Rat bekommen.Forcing Interface-Implementierungen zur Implementierung der Hierarchie in C#

Ich habe eine Klasse, die eine Unterklasse haben und eine Unterklasse hat. Der Baum dieser Klassen ist wie folgt:

Class Car 
{ 
    Wheels Wheel; 
} 
Class Wheels 
{ 
    Rims Rim; 
} 

So zu vereinfachen: ein Auto hat ein Rad und ein Rad hat eine Felge. (kann kein besseres Beispiel geben, sorry).

Also ich möchte diese Hierarchie in meiner Schnittstellenimplementierung von ICar, IWheels und IRims erzwingen.

Also habe ich so etwas wie dies (in C#):

ICar 
{ 
    IWheels Wheel; 
} 
IWheels 
{ 
    IRims Rim; 
} 

Und ich habe einen Fehler, dass ich nicht Felder in Interface-Implementierung haben können. Das hat mich dazu gebracht, dass es vielleicht ein falsches Interface-Design ist. Ich möchte Schnittstellenimplementierungen zwingen, diese Art von Hierarchie zu implementieren. Aber vielleicht, um Designmustern und Best Practices zu entsprechen, sollte es auf andere Weise gemacht werden?

Können Sie mir bitte sagen, wie ich mein System so gestalten soll, dass Objekte gezwungen werden, diese Art von Hierarchie zu implementieren?

Vielleicht gibt es etwas nicht genau in meiner Frage oder ich vermisse einige wichtige Informationen. Wenn ja, bitte fragen Sie in Kommentaren.

Antwort

10

In Ihrer Schnittstelle müssen Sie deutlich machen, dass Wheels eine Eigenschaft von ICar sein sollten, da Sie nicht deklarieren können, welche Felder eine Schnittstellenimplementierung haben soll. (Felder sind innere Vorgänge, daher sollte die Schnittstelle nichts davon wissen).

interface ICar 
{ 
    IWheels Wheels 
    { 
     get; 
    } 
} 
4

Wie der Fehler sagt, können Sie keine Felder in Ihren Schnittstellen angeben. Sie können jedoch Eigenschaften angeben:

interface ICar 
{ 
    IWheels Wheel { get; set; } 
} 

interface IWheels 
{ 
    IRims Rim { get; set; } 
} 
7

Sie können keine Feld in einer Schnittstelle angeben (und Sie sollten nicht in der Lage sein - das ist eine Implementierung Entscheidung), aber Sie können eine Eigenschaft angeben:

public interface ICar 
{ 
    IWheels Wheel { get; set; } 
} 

public interface IWheels 
{ 
    IRims Rim { get; set; } 
} 

Sie wollen nur kann gut obwohl die Getter in der Schnittstelle setzen - es ist etwas ungewöhnlich, dass ein Setter in einer Schnittstelle umfassen:

public interface ICar 
{ 
    IWheels Wheel { get; } 
} 

public interface IWheels 
{ 
    IRims Rim { get; } 
} 

(Es gibt Merkwürdigkeiten, wenn Sie eine vorhandene (oder abstrakte) Eigenschaft überschreiben wollen, die nur einen Getter hat, um einen Setter hinzuzufügen, aber es ist in Ordnung, eine "Nur-Getter" -Schnittstelle mit Setter zu implementieren, glaube ich.)

4

Sie können keine Felder deklarieren, aber Sie können Eigenschaften deklarieren. Dies hat den gleichen Effekt, dass eine bestimmte Klasse gezwungen wird, eine Instanz einer anderen Klasse bereitzustellen.

ICar 
{ 
    IWheels Wheel { get; set; } 
} 
IWheels 
{ 
    IRims Rim { get; set; } 
} 
0

Ich bin nicht so viel zu C# verwendet, aber es klingt für mich, dass Sie, dass die Umsetzung, indem sie Abstrakte Klassen zwingen kann, mit den Feldern, die Sie verwenden möchten. Also, wenn Sie diese abstrakten Klassen erweitern, haben Sie die Felder in ihnen verfügbar. Sie müssen eine abstrakte Klasse und eine Schnittstelle obwohl ...

0

Hier ist es ein voll funktionsfähiger Code ... Hoffen, es hilft ...

using System; 
using System.Collections.Generic; 
using System.Text; 

namespace ConsoleApplication10 
{ 
    //Interfaces 

    public interface ICar 
    { 
     string name { get;} 
     IWheel wheel { get;} 
    } 


    public interface IWheel 
    { 
     string brand { get;} 
    } 

    //Implementations 

    public class Michelin : IWheel 
    { 
     #region IWheel Members 

     public string brand 
     { 
      get { return "michelin"; } 
     } 

     #endregion 
    } 


    public class Toyota : ICar 
    { 
     Michelin m = new Michelin(); 
     #region ICar Members 

     public string name 
     { 
      get { return "toyota"; } 
     } 

     public IWheel wheel 
     { 
      get { return m; } 
     } 

     #endregion 
    } 

    //A user of the interfaces. Only cares about ICar but knows implicitly about IWheel 

    public class Stand 
    { 
     public Stand() 
     { 
      cars = new List<ICar>(2); 
      cars.Add(new Toyota()); 
      cars.Add(new Toyota()); 
     } 
     List<ICar> cars; 

     public string ShowCars() 
     { 
      StringBuilder str = new StringBuilder(); 
      foreach (ICar iterCar in cars) 
      { 

       str.AppendLine(string.Format("car {0} with wheel {1}", 
        iterCar.name, iterCar.wheel.brand)); 
      } 
      return str.ToString(); 
     } 
    } 

    //entry point. creates a stand and shows the cars, testing that properties are visible 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Stand myLittleStand = new Stand(); 
      Console.WriteLine(myLittleStand.ShowCars()); 
     } 
    } 
} 
+0

Natürlich folgendes Best Practices sollten Eigenschaften Versalien und Strings werden sollten nicht hart codiert werden, aber ich denke, Das sind kleine Details –

Verwandte Themen