2009-06-19 12 views
1

Sagen wir, ich möchte ein abstraktes System zum Zählen von Abschnitten in einem Dokument entwerfen. Ich entwarf zwei Klassen, Dokument und Abschnitt, das Dokument hat eine Liste von Abschnitten und eine Methode, um sie zu zählen.Kann ich eine abstrakte Klasse ableiten, die eine andere abstrakte Klasse hat, die ebenfalls unterklassifiziert ist? (C#)

public abstract class Document { 
    List<Section> sections; 

    public void addSection(Section section) { 
    sections.Add(section); 
    } 
    public int sectionCount() { 
    return sections.count; 
    } 
} 
public abstract class Section { 
    public string Text; 
} 

Nun möchte ich diesen Code in mehreren Szenarien verwenden können. Zum Beispiel habe ich Bücher mit Kapiteln. Das Buch wäre eine Unterklasse des Dokuments und Kapitel eine Unterklasse des Abschnitts. Beide Klassen enthalten zusätzliche Felder und Funktionen, die nichts mit dem Zählen von Abschnitten zu tun haben.

Das Problem stolperte ich jetzt ist, dass, weil Dokument Abschnitte und nicht Kapitel enthält, die zusätzliche Funktionalität von Kapitel für mich nutzlos ist, kann es als Abschnitt zu Buch hinzugefügt werden.

Ich habe über Downcasting gelesen, aber ich denke wirklich, dass dies nicht der richtige Weg ist. Ich denke, dass ich vielleicht den falschen Weg eingeschlagen habe.

Meine Frage lautet: Wie entwerfe ich ein solches abstraktes System, das von unterklassierten Objekten wiederverwendet werden kann, und ist das der Weg?

+0

Obwohl ich stimme zu, dass Jons Antwort tatsächlich deine Frage beantwortet, würde ich geneigt sein, hier einen Schritt zurück zu machen und zu fragen, ob du vielleicht nicht an etwas von dem, was ich "Object Happiness Syndrom" nenne, leidest. Müssen Sie wirklich Dokumente und Abschnitte polymorph über eine große Menge möglicher Dokument-/Abschnittstopologien hinweg behandeln? Erhöht sich die zusätzliche Komplexität und damit die zusätzlichen Kosten Ihrer komplizierten Typbeziehungen in Bezug auf die Wiederverwendung von Code in großem Maßstab durch Polymorphie und Vererbung oder ist es nur OOP für OOP? –

+0

Eric, du könntest recht haben. Vielleicht ist es zu viel und ich füge zu viel Komplexität hinzu, ich habe mich selbst darüber gewundert. Aber ich habe das Gefühl, ich weiß nicht, ob das der Fall ist oder nicht. Was ich wirklich erreichen möchte, ist ein abstraktes "System", das ich wiederverwenden kann und nicht mit Dingen wie Persistenz überladen ist. Im oben genannten Fall hätte Book die zusätzliche Funktion, sich persistent zu halten (mit ORM). –

Antwort

6

Sie müssen Generika:

public abstract class Document<T> where T : Section 

public abstract class Section 

public class Book : Document<Chapter> 

public class Chapter : Section 

Sie könnten auch einen Abschnitt wissen wollen, welche Art von Dokument kann es ein Teil sein. Leider das wird viel komplizierter:

public abstract class Document<TDocument, TSection> 
    where TDocument : Document<TDocument, TSection> 
    where TSection : Section<TDocument, TSection> 

public abstract class Section<TDocument, TSection> 
    where TDocument : Document<TDocument, TSection> 
    where TSection : Section<TDocument, TSection> 

public class Book : Document<Book, Chapter> 

public class Chapter : Section<Book, Chapter> 

ich diese Puffer in Protokoll hätte zu tun, und es ist chaotisch - aber es ermöglicht es Ihnen, in beiden Richtungen in eine stark typisierten Weise zu verweisen. Ich würde für die erste Version gehen, wenn Sie damit durchkommen können.

+0

Vielen Dank Jon, bastelte den Tag für einen ganzen Tag! Ich werde mich über Generika informieren, aber es scheint, dass ich danach suche. –