简体   繁体   中英

Can I subclass a abstract class which has another abstract class which is also subclassed? (C#)

Lets say I want to design a abstract system for counting sections in a document. I designed two classes, Document and Section , the document has a list of sections and a method to count them.

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

Now, I want to be able to use this code in multipe scenarios. For example, I have Books with Chapters. The Book would be a subclass of Document, and Chapter a subclass of Section. Both classes will contain extra fields and functionality, unrelated to the counting of sections.

The problem I stumble upon now is that because Document contains sections, and not Chapters, the added functionality of Chapter is useless to me, it can only added as a section to Book.

I was reading about downcasting, but really think this is not the right way to go. I'm thinking maybe I took the wrong approach altogether.

My question comes to this: How do I design such an abstract system, that can be reused by subclassed objects, and is this the way to go?

You need generics:

public abstract class Document<T> where T : Section

public abstract class Section

public class Book : Document<Chapter>

public class Chapter : Section

You might also want to make a section know what kind of document it can be part of. Unfortunately that becomes a lot more complicated:

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>

I've had to do this in Protocol Buffers, and it's messy - but it does allow you to reference both ways in a strongly-typed way. I'd go for the first version if you can get away with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM