Что такое отказано по завещанию?
Может кто-нибудь объяснить, что означает " Отказался от завещания"? Я попытался прочитать некоторые статьи и сказал, что это своего рода запах кода или в вики он говорит, что это класс, который переопределяет метод базового класса таким образом, что контракт базового класса не соблюдается производным классом.
Но в двух словах или, проще говоря, что это на самом деле?
1 ответ
Я думаю, вы поняли. Отказался от завещания - это кодовый запах. Но какой тип кода пахнет? Цитирую книгу Мартина Фаулера Рефакторинг: улучшение дизайна существующего кода:
Подклассы получают наследовать методы и данные своих родителей. Но что, если они не хотят или нуждаются в том, что им дают? Они получают все эти замечательные подарки и выбирают лишь несколько, чтобы поиграть.
У вас есть подкласс, который наследуется от родительского класса, но подклассу не нужно все поведение, обеспечиваемое родительским классом. Из-за этого подкласс отказывается от некоторого поведения (завещания) родительского класса. Вот почему это запах кода.
Обновление ответа на комментарий @catzilla:
Если у вас нет возможности прочитать книгу (я полностью рекомендую ее), по крайней мере, у вас есть страница SourceMaking, которая описывает ее довольно хорошо.
О примере кода, давайте попробуем. Давайте представим, что у нас есть несколько классов для расчета налогов человека. У нас может быть класс, который вычисляет государственные налоги:
class Government {
protected double computeBaseTax() { //... }
protected double addPersonalTax(double tax) { //... }
public double getTax() {
double tax = computeBaseTax();
return addPersonalTax(tax);
}
}
Тогда у нас может быть класс, который вычисляет сумму денег, которую компания должна заплатить в качестве налогов. По какой-то причине мы поняли, что этот класс может использовать addPersonalTax
метод, но не computeBaseTax()
, И, приняв плохое решение, мы решили, что наши Company
класс будет наследовать от Government
,
class Company extends Government {
private double computeInitialTax() { //... }
@Override
public double getTax() {
double tax = computeInitialTax();
return addPersonalTax(tax);
}
}
Хорошо, проблема может быть решена лучше (переопределение computeBaseTax()
метод), но я пытаюсь проиллюстрировать, что Refused Bequest - это запах кода, который возникает, когда мы наследуем от базового класса, а некоторые предоставляемые функции отклоняются.