На этом шаге мы рассмотрим назначение такой реализации.
Мы уже неоднократно говорили: интерфейсы определяют, что надо реализовать, а не как. Тем не менее есть возможность определить реализацию по умолчанию для методов чтения свойств и функций в интерфейсе. Классы, реализующие интерфейс, могут использовать реализацию по умолчанию или определить свою.
Добавьте метод чтения по умолчанию для damageRoll в Fightable. Он должен возвращать сумму очков, выпавших на всех костях, чтобы определить величину урона, нанесенного противнику в одном раунде битвы.
package com.bignerdranch.nyethack interface Fightable { var healthPoints: Int val diceCount: Int val diceSides: Int val damageRoll: Int get() = (0 until diceCount).map { Random().nextInt(diceSides + 1) }.sum() fun attack(opponent: Fightable): Int }
Рис.1. Объявление реализации геттера по умолчанию (Creature.kt)
Теперь, когда damageRoll имеет метод чтения по умолчанию, любой класс, реализующий интерфейс Fightable, может отказаться от определения своей реализации свойства damageRoll и использовать значение, возвращаемое реализацией по умолчанию.
Не каждому свойству или функции нужна уникальная реализация в каждом классе, поэтому определение реализации по умолчанию - это хороший способ сократить повторы в вашем коде.
На следующем шаге мы рассмотрим абстрактные классы.