Могу ли я создать подкласс абстрактного класса, который имеет другой абстрактный класс, который также подкласс? (С #) - PullRequest
1 голос
/ 19 июня 2009

Допустим, я хочу разработать абстрактную систему подсчета разделов в документе. Я разработал два класса, Документ и Раздел , в документе есть список разделов и метод их подсчета.

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

Теперь я хочу использовать этот код в нескольких сценариях. Например, у меня есть Книги с главами. Книга будет подклассом документа, а глава - подклассом раздела. Оба класса будут содержать дополнительные поля и функции, не связанные с подсчетом секций.

Проблема, с которой я сейчас сталкиваюсь, состоит в том, что поскольку Document содержит разделы, а не главы, добавленные функциональные возможности Chapter для меня бесполезны, он может только добавить как раздел к Book.

Я читал об унынии, но действительно думаю, что это неправильный путь. Я думаю, может быть, я вообще ошибся.

Мой вопрос сводится к следующему: как мне спроектировать такую ​​абстрактную систему, которая может быть повторно использована подклассами, и так ли это?

1 Ответ

6 голосов
/ 19 июня 2009

Вам нужны дженерики:

public abstract class Document<T> where T : Section

public abstract class Section

public class Book : Document<Chapter>

public class Chapter : Section

Вы можете также хотеть, чтобы раздел знал, к какому типу документа он может быть. К сожалению, это становится намного сложнее:

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>

Мне приходилось делать это в протокольных буферах, и это грязно - но это позволяет вам ссылаться на оба пути строго типизированным способом. Я бы пошел на первую версию, если вы можете сойти с рук.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...