2016-07-18 33 views
0

Wenn ich eine Elternklasse oder Schnittstelle und 2 Kindklassen habe, die vom Elternteil erben oder die Schnittstelle implementieren, habe ich gemeinsame Eigenschaften im Elternteil, aber es gibt einige Eigenschaften in jedem Kind. Sollte ich alle Eigenschaften in der Elternklasse/Schnittstelle sammeln oder trennen?Eigenschaften der Elternklasse

abstract class Customer 
{ 
    string name { get; set; } 
} 

class GoldCustomer : Customer 
{ 
    string Address { get; set;} 
} 

class SilverCustomer : Customer 
{ 
    string Telephone { get; set;} 
} 

Wenn ich sich dann trennen und einen Verweis von der Mutter erstellen, um das Kind zeigt dann kann es dem Kind nicht Eigenschaften getrennt zugreifen

Customer c = new GoldCustomer(); 
c.Address // error 

Welche richtige Architektur und nicht jedes Design zu verletzen Muster?

abstract class Customer 
{ 
    string name { get; set; } 
    string Address { get; set;} 
    string Telephone { get; set;} 
} 

class GoldCustomer : Customer 
{ 

} 

class SilverCustomer : Customer 
{ 

} 


Customer c = new GoldCustomer(); 
c.Address = ""; 
+0

Es hängt von den genauen Umständen ab. Entwerfen Sie Ihre Klassen so, dass Sie nicht gegen das Liskov-Substitutionsprinzip verstoßen müssen (https://en.wikipedia.org/wiki/Liskov_substitution_principle). Wenn Sie das schwierig finden, denken Sie an die Zusammensetzung statt an die Vererbung (https: // en .wikipedia.org/wiki/Composition_over_inheritance) – itsme86

+0

Diese Frage ist zu weit gefasst und wie es heißt, kommt es auf bestimmte Umstände an. Beide Vorgehensweisen könnten korrekt sein, es hängt nur davon ab, was Sie tun möchten. Versuchen Sie einfach vorher zu überlegen, was Sie wirklich brauchen, damit Sie keine unnötigen Abhängigkeiten machen. – CrudaLilium

Antwort

0

Statt Vererbung verwenden, würde ich wahrscheinlich für einen separaten Satz von Klassen entscheiden, die die unterschiedlichen Kontaktinformationen für die Kundentypen enthalten:

public class Customer 
{ 
    public string Name { get; } 
    public ContactInfo ContactInfo { get; } 
    // Other common properties 
} 

public abstract class ContactInfo 
{ 
    public virtual string Address => ""; 
    public virtual string Telephone => ""; 
} 

public class GoldContactInfo : ContactInfo 
{ 
    public override string Address { get; } 
} 

public class SilverContactInfo : ContactInfo 
{ 
    public override string Telephone { get; } 
} 
1

ich den Ansatz ändern würde von @ itsme86 einem wenig, so dass ich die Address oder Telephone nur auf einer bestimmten ContactInfo:

public class Customer<T> where T : IContactInfo 
{ 
    public string Name { get; } 
    public T ContactInfo { get; } 
} 

public interface IContactInfo 
{ } 

public class GoldContactInfo : IContactInfo 
{ 
    public string Address { get; } 
} 

public class SilverContactInfo : IContactInfo 
{ 
    public string Telephone { get; } 
} 

public class GoldCustomer : Customer<GoldContactInfo> 
{ 
    // Here does the GoldCustomer have a GoldContactInfo 
} 

public class SilverCustomer : Customer<SilverContactInfo> 
{ 
    // Here does the SilverCustomer have a SilverContactInfo 
} 
+0

Okay, wie fragt ein Anrufer nach einer Kundenadresse? Sie werden wahrscheinlich auf etwas wie "if (typeof (T) == typeof (GoldContactInfo)" zurückgreifen. Es sei denn, Sie haben einen anderen Trick? Es scheint zu fest an mich gebunden. Sie wollen nicht den 'Kunden "Klasse, die etwas über den' ContactInfo' Typ wissen muss. Das ist der ganze Sinn der Komposition. – itsme86

+0

@ itsme86 Zuerst habe ich nie gesagt, dass der Typ 'T' nicht benötigt wird. Ich habe nur Ihren Ansatz geändert, weil Sie es erwähnt haben bevor die Frage breit ist und ich eine andere Herangehensweise zeigen wollte. Zweitens denke ich, dass die Komposition viel mehr Vorteile hat als nur "Sie möchten nicht, dass die Customer-Klasse irgendetwas über die ContactInfo-Klasse wissen muss."Siehe diese fünf Gründe zum Beispiel http://javarevisited.blogspot.co.at/2013/06/why-favor-composition-over-interitance-java-oops-design.html –

0

Wenn das denken abou t Vererbung und Eigenschaften ist die einfachste Methode, sie in Begriffen von "ist-a" und "hat-a" zu denken.

Hat eine Customer eine Address? Wie wäre es mit einem Telephone? Wenn ein allgemeines Customer keine Adresse hat, dann macht folgende keinen Sinn:

Customer c = new GoldCustomer(); 
c.Address = ""; // Customer does not have an Address property 

Die Tatsache, dass das tatsächlichen Objekt tut haben eine Address Eigenschaft irrelevant ist. Sie haben es als Customer Variable deklariert, so dass der Compiler es als solches behandelt.

Wenn alle Kunden eine Adresse und Telefon haben, was andere Eigenschaften oder Verhaltensweisen machen eine SilverCustomer von einem "normalen" Kunden unterscheiden? Sie könnten auch feststellen, dass ein Attribut von Custmoer, das den Level angibt, einfacher ist, aber es hängt von der tatsächlichen Verwendung ab.