Наследование указанных методов в 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 как необходимо. Понятно, какие методы принадлежат к каким типам. Не заблуждайтесь, что в больших проектах объем работы для этого будет масштабироваться, но это может привести к более чистому коду.

Другие вопросы по тегам