Предположим, что у меня есть класс, моделирующий статьи расходов, называемые Expense. У нас есть расходы на транспортировку, питание и заработную плату. Предположим, что все свойства одинаковы, поэтому существует только один класс Expense с свойством типа. Однако предположим, что я добавляю новый тип расходов, называемый обучением, и для этого требуются новые поля, касающиеся типа обучения, местоположения и даты. Кроме того, существует несколько новых методов, характерных для этого расхода обучения. Поэтому на данный момент мне нужно подклассифицировать класс Expense, чтобы у меня был класс TrainingExpense. Поскольку подкласс теперь определяет тип расходов, делает ли это избыточным свойство «type» в базовом классе Expense? Должен ли я теперь просто подклассифицировать базовый класс Expense для каждого другого типа? Или я должен просто оставить свойство type в базовом классе и иметь его избыточным для любых подклассов?Наследование классов с пустыми подклассами
ответ
Вместо наследования я бы использовал композицию здесь. Создайте свойство say ExpenseExtension типа интерфейса IExpenseExtension
в базовом классе.
Для типов расходов, которые имеют дополнительные свойства/методы, наследуются от IExpenseExtension и добавляют дополнительные свойства/методы, необходимые. В случае TravelExpense он будет иметь класс TravelExpenseExtension
, который наследует от IExpenseExtension дополнительные свойства/методы, которые вам нужны.
В базовом классе создайте соответствующий класс ExpenseExtension
на основе свойства ExpenseType
.
Использование композиции вместо наследования здесь сделает ее более гибкой.
Я также предлагаю вам создать перечисление со всеми типами и использовать его для свойства ExpenseType.
Проверьте ниже Url, чтобы прочитать о композиции против наследования:
http://lostechies.com/chadmyers/2010/02/13/composition-versus-inheritance/
по ссылке: Отдавая состав объекта над наследованием класса поможет вам сохранить каждый класс инкапсулируется и сосредоточен на одной задаче. Ваши классы и иерархии классов останутся маленькими и будут менее склонны превращаться в неуправляемых монстров.
UPDATE: Смотрите ниже пример кода в C#:
public class Expense
{
public string Food { get; set; }
public ExpenseType Type { get; set; }
private IExpenseExtension expenseExtension;
public IExpenseExtension ExpenseExtension
{
get
{
if(expenseExtension == null)
{
// Logic to instantiate the correct Extension based on Type property.
// You can use Factory design pattern or something like that for this as well.
}
return expenseExtension;
}
}
}
public interface IExpenseExtension
{
}
public class TrainingExpenseExtension : IExpenseExtension
{
public string Location { get; set; }
public void GetTrainingDetails()
{
}
}
Другой подход может быть определить интерфейс IExpense, а затем реализовать, так что все ваши «стандартные» модели поведения доступны через интерфейс и специальный поведения через класс. Композиционный подход, как blacktie24, но перевернутый. Все зависит от того, как вы собираетесь получить доступ к дополнительным материалам.
- 1. Проблем с подклассами и Наследование
- 2. Как сопоставить наследование с подклассами
- 3. Определение массива классов с подклассами
- 4. Абстрактное однотонное наследование с несколькими подклассами
- 5. Наследование Python Test с несколькими подклассами
- 6. Расширение классов Java с различными подклассами
- 7. HTML. Назначить несколько классов с подклассами элементу
- 8. Аннотация Наследование классов Наследование
- 9. Как работать с динамическими подклассами
- 10. Наследование классов с иерархией
- 11. Наследование отдельных таблиц или наследование классов классов?
- 12. Doctrine2 Наследование классов классов
- 13. Наследование классов
- 14. Наследование классов и классное литье
- 15. C++ Наследование классов с функциями
- 16. Наследование классов, смешанное с шаблонами
- 17. Множественное наследование с использованием классов
- 18. Наследование классов и литье
- 19. Total_ordering и наследование классов
- 20. RequireJS и наследование классов
- 21. Наследование нескольких классов
- 22. Наследование и извлечение классов
- 23. Дизайн и наследование классов
- 24. Наследование внутри классов Python3
- 25. Django Наследование из классов
- 26. Наследование классов по файлам
- 27. OPPS - наследование классов
- 28. Наследование таблицы классов Sequel
- 29. наследование классов в Symfony2
- 30. наследование классов не найден
Thx, мне очень нравится это решение. Но что мне делать с дополнительными методами? – blacktie24
То же самое. Добавьте его в класс ExpenseExtension. Используйте расширение имени вместо полей, поэтому назовите его IExpenseExtension и TravelExpenseExtension. –
Я только что обновил ответ, чтобы сказать «Расширение вместо полей», но вы можете выбрать имя, которое вам нравится. –