Наследование указанных методов в Java
Возможно ли в Java наследовать некоторые методы из базового класса, но не все из них? Просто чтобы прояснить, я покажу вам, что я имею в виду: предположим, у нас есть посетитель базового класса
public abstract class Visitor {}
Из Visitor мы создаем еще 2 объекта, клиента и компаньона:
public class Client extends Visitor {}
public class Companion extends Visitor {}
В клиенте мы создаем метод:
boolean has_Companion() {}
Для достижения полиморфизма во время выполнения нам нужно также объявить метод в Visitor:
abstract boolean has_Companion();
Проблема в том, что, поскольку мы объявляем метод в Visitor, Companion также наследует его. Мы этого не хотим. Когда я компилирую, я получаю следующую ошибку:
Тип Companion должен реализовывать унаследованный абстрактный метод Visitor.has_Companion()
Нет смысла в реализации метода has_Companion () для Companion, потому что он никогда не будет использоваться. Это пустая трата кода. Могу ли я избежать этого каким-либо образом? Может ли метод has_Companion () наследоваться только клиентом, а не Companion?
1 ответ
Короткий ответ: Java не поддерживает то, что вы пытаетесь сделать, но хорошая новость в том, что есть много способов обойти это.
Идея 1: есть Companion
переопределение hasCompanion
и просто всегда возвращаюсь false
,
Идея 2: есть Visitor
обеспечить реализацию hasCompanion
это просто всегда возвращается false
, Тогда клиент переопределит hasCompanion
с реальной логикой, чтобы определить, есть ли у клиента компаньон.
Идея 3: не давать hasCompanion
метод для Visitor
вообще, а точнее есть только метод в Client
, Затем код имеет проверку типа во время выполнения через instanceof
оператор и вызывает метод на Client
через кастинг. Пример:
if (visitor instanceof Client) {
Client client = (Client) visitor;
boolean hasCompanion = client.hasCompanion();
// other logic
}
Это в лучшем случае фальшивый полиморфизм и очень грязное решение. Я бы посоветовал не делать этого, если это возможно.
Идея 4: пересмотреть дизайн и реорганизовать дерево типов и то, как код использует наследование. Если нет смысла звонить hasCompanion
на Companion extends Visitor
, почему hasCompanion
метод Visitor
совсем?
Java не поддерживает множественное наследование, поэтому необходимы интерфейсы:
public interface MightHaveCompanion {
public boolean hasCompanion();
}
public abstract class Visitor {
// methods that all Visitors must have
}
public class Client extends Visitor implements MightHaveCompanion {
// overriding implementations of MightHaveCompanion and Visitor methods
}
public class Companion extends Visitor {
// overriding implementations of Visitor methods
}
Тогда вызывающий код должен будет измениться, чтобы использовать типы MightHaveCompanion
или же Visitor
как необходимо. Понятно, какие методы принадлежат к каким типам. Не заблуждайтесь, что в больших проектах объем работы для этого будет масштабироваться, но это может привести к более чистому коду.