Почему в Java нет множественного наследования классов
Что проверяют
Понимаете ли вы, какую конкретно проблему авторы языка обошли, и знаете ли, чем множественное наследование заменяют на практике.
Как отвечать
Класс в Java наследуется ровно от одного класса. Причина в неоднозначности, которую даёт наследование состояния и реализации сразу от нескольких предков. Классический пример это ромбовидное наследование: B и C наследуются от A, D наследуется от B и C, и непонятно, чью реализацию метода и чью копию полей получает D. Языки, где это разрешено, вынуждены вводить сложные правила разрешения конфликтов, а код становится трудно предсказуемым.
Java выбрала простоту: одно наследование состояния плюс сколько угодно интерфейсов. Интерфейс задаёт поведение без полей, поэтому конфликта состояния не возникает.
class Service extends BaseService implements Runnable, AutoCloseable { }Стоит упомянуть, что с Java 8 у интерфейсов появились default-методы, и ограниченный конфликт реализаций стал возможен: если два интерфейса дают одинаковый default-метод, компилятор потребует переопределить его явно, и вызвать нужный можно через Interface.super.method(). Состояние при этом по-прежнему не наследуется, поэтому ромб не возвращается.
Практическая часть ответа: вместо наследования от нескольких классов используют композицию, то есть держат нужные объекты полями и делегируют им работу. Это гибче, не ломается при изменении базового класса и лучше соответствует принципу единственной ответственности.
Где спотыкаются
Говорят «в Java нет множественного наследования» без уточнения. Множественное наследование типов есть, нет наследования состояния и реализации от нескольких классов.
Не знают про default-методы и правило явного переопределения при конфликте.
Приводят наследование там, где напрашивается композиция. Вопрос часто продолжают именно этим: «а как бы вы сделали, если поведение нужно от двух источников».