Ответ
Java не поддерживает множественное наследование классов для избежания проблемы "ромбовидного наследования" (неоднозначность вызова метода, если он определён в двух родительских классах).
Однако, начиная с Java 8, можно эмулировать множественное наследование поведения с помощью интерфейсов с default-методами.
Пример и решение конфликта:
interface Logger {
default void log(String message) {
System.out.println("LOG[" + getClass().getSimpleName() + "]: " + message);
}
}
interface Serializer {
default void log(String message) { // Конфликт имён!
System.out.println("Serialization log: " + message);
}
String serialize();
}
// Класс ДОЛЖЕН явно разрешить конфликт
class DataProcessor implements Logger, Serializer {
private String data;
// Способ 1: Предоставить свою реализацию
@Override
public void log(String message) {
System.out.println("DataProcessor: " + message);
}
// Способ 2: Делегировать вызов конкретному интерфейсу
public void logAsSerializer(String msg) {
Serializer.super.log(msg); // Явный вызов реализации из Serializer
}
@Override
public String serialize() { return "Processed: " + data; }
}
Важные ограничения:
- Наследуется только поведение (методы), но не состояние (поля). Интерфейсы могут содержать только
static finalконстанты. - Класс-наследник обязан переопределить метод, если у него есть конфликтующие
default-реализации из нескольких интерфейсов. - Приоритет: реализация в классе >
default-метод в интерфейсе.
Альтернатива: Композиция. Часто композиция (включение объектов с нужным поведением) предпочтительнее сложной иерархии интерфейсов.
class DataProcessor {
private Logger logger = new ConsoleLogger();
private Serializer serializer = new JsonSerializer();
void process() {
logger.log("Start");
String result = serializer.serialize();
logger.log("Result: " + result);
}
}