webprogr.ru Новости

RSS

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...


Последние новости

Лабораторная работа № III : Наследование и полиморфизм

(проект лабораторной, по итогам принятия лабораторной 2 может меняться) Лабораторная работа № 3 — «Наследование, интерфейсы и полиморфизм»

Здесь происходит ключевой переход: в первой лабораторной студент видел готовую иерархию Delivery; теперь он должен самостоятельно понять, когда и зачем строить иерархию.

Класс предыдущей работы рефакторится в:

                 Transaction
                      ▲
          ┌───────────┼───────────┐
          │           │           │
 IncomeTransaction ExpenseTransaction TransferTransaction

                    interfaces
                         │
                  Commissionable

Базовый класс:


public abstract class Transaction {

    private final UUID id;
    private final LocalDate date;
    private final BigDecimal amount;

    protected Transaction(
            UUID id,
            LocalDate date,
            BigDecimal amount
    ) {
        // validation
    }

    public final UUID getId() {
        return id;
    }

    public final BigDecimal getAmount() {
        return amount;
    }

    public abstract BigDecimal balanceImpact();
}

Конкретные классы должны самостоятельно реализовать balanceImpact():

доход       →  +amount
расход      →  -amount
перевод     →  поведение определяется стороной операции

Через массив или обычный цикл, без instanceof и без switch по типу:

Transaction[] transactions = { ... };

for (Transaction transaction : transactions) {
    total = total.add(transaction.balanceImpact());
}

студент должен увидеть позднее связывание в коде, который уже написал сам. Java позволяет классу иметь один непосредственный суперкласс, а интерфейсы используются как отдельные контракты типа; это хорошо подходит для явного сравнения «abstract class vs interface».

Для интерфейса можно использовать:


public interface Commissionable {
    BigDecimal commission();
}

и реализовать его только там, где комиссия действительно существует. Это даёт естественный вопрос: почему Commissionable не нужно делать родителем всей иерархии?

Вторая часть — overloading vs overriding. Студент должен показать в одном проекте:


// overloading
print(Transaction transaction)
print(Transaction[] transactions)

// overriding
@Override
public BigDecimal balanceImpact()

и объяснить, какое решение принимает компилятор, а какое определяется фактическим типом объекта во время выполнения.

Третья часть — Object. В Java Object является корнем иерархии классов. Для Transaction требуется реализовать:


@Override
public boolean equals(Object obj) { ... }

@Override
public int hashCode() { ... }

@Override
public String toString() { ... }

Рекомендуемое правило лабораторной: идентичность транзакции определяется UUID id. Затем студент проверяет:

t1.equals(t2)
t1.hashCode() == t2.hashCode()

и отвечает, почему при переопределении equals() необходимо согласованно реализовывать hashCode(). Контракт Java прямо требует, чтобы равные согласно equals() объекты имели одинаковый hash code.

Индивидуальное расширение: добавить новый подтип транзакции из варианта преподавателя — CashbackTransaction, InterestTransaction, TaxTransaction, RefundTransaction — не изменяя полиморфный алгоритм вычисления общего влияния на баланс.

Запрещено: if (transaction instanceof IncomeTransaction), поле type для выбора поведения, switch по имени класса.

Автопроверка: вызов balanceImpact() для каждого подкласса; полиморфный расчёт; корректность equals/hashCode; невозможность прямого создания new Transaction(...); проверка новой реализации без изменения агрегирующего алгоритма.

Защита: extends; super; перегрузка vs переопределение; @Override; статический и динамический тип ссылки; late binding; abstract class vs interface; почему Java не требует, чтобы каждый общий контракт был абстрактным классом; роль Object; назначение toString, equals, hashCode.

Вопросы для углубления: Что такое наследование и как используется

extends?Чем отличается перегрузка от

переопределения методов?Что такое полиморфизм

времени выполнения и позднее связывание?

Абстрактные классы и интерфейсы: в чем

различия и когда что применять?Какую роль

играет класс Object и методы toString(), equals(),

hashCode()?


Рейтинг@Mail.ru