Наследование VB.NET - все ли свойства в производных классах должны быть объявлены в базовом классе? - PullRequest
2 голосов
/ 08 августа 2011

Я занимаюсь рефакторингом и столкнулся с контрольно-пропускным пунктом.

Справочная информация:

У меня есть базовый класс и несколько унаследованных производных классов. Производные классы не всегда должны иметь одинаковые свойства. Если какие-либо свойства являются общими для производных классов, эти свойства будут жить на уровне базового класса (например, ' Contents ').

Аналогично, нижеприведенный GoodDocument имеет ' GoodThings ', но не хочет / не должен иметь ' BadThings '.

Я хочу обрабатывать экземпляры ' GoodDocument ' и ' BadDocument ' как тип ' Документ '

public mustinherit class Document
  public property Contents as string
  public sub new()...
end class 

public class GoodDocument
  inherits Document
  public property GoodThings as string
  public sub new()...
end class

public class BadDocument
  inherits Document
  public property BadThings as string
  public sub new()...
end class

Класс ' DocumentWriter ' также будет иметь несколько производных классов: (' GoodDocumentWriter ' и ' BadDocumentWriter ').

Мне нужно передать DocumentWriter.Doc как «Документ» ряду других мест в коде. Doc.GoodThings вызывается только из экземпляра GoodDocument или GoodDocumentWriter.

public mustinherit class DocumentWriter
  public property Doc as Document
  public sub new()... 
end class

public class GoodDocumentWriter
  inherits DocumentWriter
  public sub new 
    mybase.Doc = new GoodDocument
  end sub
end class

public class BadDocumentWriter
  inherits DocumentWriter
  public sub new 
    mybase.Doc = new BadDocument
  end sub
end class

Вопрос:

  • Существует ли шаблон проектирования, который позволяет производным классам иметь членов, которых не существует на уровне базового класса?

  • Должны ли все свойства жить на уровне базового класса?

Пересмотренный

Я пытался быть кратким с моим первоначальным вопросом, и я сделал ошибку, упрощая ситуацию. Короче говоря, я понял, что должно быть возможно иметь разные свойства для каждого из производных классов. (Я напечатал это в издевательстве и не хотел оставлять это в последнем посте).

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

Похоже, что я сталкивался с жалобами компилятора, которые можно было исправить путем дальнейшего рефакторинга и более слабой связи. В то время как другие ответили на основной вопрос, который я поставил, пример Райана Гросса действительно помог начать некоторые новые идеи.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 08 августа 2011

Что вы должны сделать в этом случае, это определить операции, которые могут быть выполнены для экземпляров Document в интерфейсе.В вашем случае, возможно, есть операция WriteThings, поэтому вы должны иметь:

public interface Writeable {
    public sub WriteThings();
}

Затем в ваших производных классах вы реализуете метод для использования внутренних данных класса.Например:

public mustinherit class Document implements Writeable
  public property Contents as string
  public sub new()...
  public sub WriteThings();
end class 

public class GoodDocument
  inherits Document
  public property GoodThings as string
  public sub new()...
  public sub WriteThings()
     //Do something with GoodThings
  end sub
end class

public class BadDocument
  inherits Document
  public property BadThings as string
  public sub WriteThings()
     //Do something with BadThings
  end sub
  public sub new()...
end class

Наконец, клиентский код, который должен вызывать WriteThings, обращается к нему через интерфейс:

public mustinherit class DocumentWriter
  public property Doc as Writable
  public sub new()... 
  public sub PerformWrite()
    Doc.WriteThings();
  end sub
end class

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

1 голос
/ 08 августа 2011

Если все свойства живут на уровне базового класса, тогда я не уверен, какой смысл будет иметь производный класс.:) Вы могли бы делать все с базовым классом.

Итак, да.Если что-то применимо только к GoodDocument, а не к Document, то это должно быть в GoodDocument.

0 голосов
/ 08 августа 2011

Чтобы конкретно ответить на ваш вопрос:

  • Да, вы просто создаете несколько слоев в иерархии наследования: у вас есть базовый класс, а затем много двух «ветвей» (хороших и плохих), чтобы использовать вашу терминологию).Любые свойства, которые имеют отношение только к любой ветви, вы объявляете в классе, который наследуется от базового класса.Эти свойства будут видны только этому классу и любым классам, унаследованным от него.

  • Нет, свойства могут быть объявлены в любом месте иерархии наследования.

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