Почему интерфейс Java не может быть реализован менее специфичной функцией - PullRequest
0 голосов
/ 06 июня 2018

Почему я не могу сделать это в Java:

interface Context{
    void add(Integer o);
}
class Subclass implements Context{
    @Override
    public void add(Object o){...}
}

Разве Subclass.add уже не реализовал бы Context.add, поскольку add (Object) может выполнить все, что может добавить (Integer)?

Какой хороший способ обойти это?

Прямо сейчас я делаю некрасивый способ:

private void actuallyAdd(Object o){...}
public void add(Object o){actuallyAdd(o);}
public void add(Integer o){actuallyAdd(o);}

РЕДАКТИРОВАТЬ: это не дубликат вышеупомянутого вопроса.В данном вопросе суперкласс является тем, который имеет более общий «Объект» в качестве параметра, в то время как подкласс является более конкретным.Это не работает, так как более конкретный метод может не справиться с любым объектом.В моем вопросе подкласс менее специфичен, чем суперкласс, то есть подкласс всегда способен обрабатывать все, что требуется суперклассу.

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Это происходит потому, что компилятору Java требуется, чтобы подписи переопределяющих методов были «подписями» переопределенного метода.То есть, либо типы параметров идентичны, либо стирание типов параметров идентично.

JLS, раздел 8.4.8.1 , утверждает это следующим образом:

Метод экземпляра m C , объявленный или унаследованный классом C, переопределяет из C другой метод m I , объявленный в интерфейсе I, если все из следующегоистинны:

...

  • Подпись m C является подписью (§8.4.2) подписим I .

Раздел 8.4.2 :

Подпись метода m 1 - это подпись метода m 2 , если либо:

  • m 2 имеет такую ​​же подпись, что иm 1 или

  • подпись m 1 совпадает с удалением (§4.6) подписи m 2 .

Вы можете обойти это, объявивВызовите параметр универсального типа, как показывает другой ответ, хотя неясно, исходная цель интерфейса - взять Integer или просто какой-то определенный, но еще неизвестный тип.

0 голосов
/ 06 июня 2018

Вы можете попробовать дженерики:

interface Context<T> {
    void add(T t);
}

class Subclass implements Context<Object> {
    @Override
    public void add(Object o){...}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...