Что такое отказано по завещанию?

Может кто-нибудь объяснить, что означает " Отказался от завещания"? Я попытался прочитать некоторые статьи и сказал, что это своего рода запах кода или в вики он говорит, что это класс, который переопределяет метод базового класса таким образом, что контракт базового класса не соблюдается производным классом.

Но в двух словах или, проще говоря, что это на самом деле?

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 - это запах кода, который возникает, когда мы наследуем от базового класса, а некоторые предоставляемые функции отклоняются.

Другие вопросы по тегам