Каковы ограничения на дженерики в иерархии наследования? - PullRequest
0 голосов
/ 10 января 2019

Предположим, есть иерархия классов / интерфейсов:

class A<T>{
    T method(T t){
        return t;
    }
}
class B<T> extends A{
    T method(T t){ // method(T)' in 'B' clashes with 'method(T)' in 'A'; both methods have same erasure, yet neither overrides the other
        return t;
    }
}

Как мы видим, есть ошибка компилятора. Я никогда не сталкивался с правилами обработки дженериков при наследовании. Каковы ограничения? (пожалуйста, не путайте с наследованием в самом общем типе, я спрашиваю о наследовании в оригинальных классах

также не путайте с "Что такое необработанный тип", я знаю необработанные типы, в этом вопросе я хочу выяснить, каковы правила наследования)

также не смущайтесь, думая, что я хочу исправить эту ошибку. Конечно, класс B расширяет это исправить. Мой вопрос о том, «где я могу прочитать ограничения?»

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Вы не продлили A T, вы только что ввели новый параметр типа T для B. Эти T s отличаются, если вы не пишете B<T> extends A<T>:

class B<T> extends A<T> {
    @Override
    T method(T t) {
        return t;
    }
}

Оба A T и B T будут стерты до Object, класс B будет содержать 2 метода Object method(Object t).

Пример 8.4.8.3-4. Стирание влияет на переопределение

В классе не может быть двух методов-членов с одинаковыми именами и . Стирание

class C<T> {
    T id (T x) {...}
} 

class D extends C<String> {
    Object id(Object x) {...}
}

https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#d5e14416

Читать следующим образом: 8.4.8.3. Требования к переопределению и сокрытию

0 голосов
/ 10 января 2019

Вы скомпилировали ошибку так же, как говорит @ f1sh.

Теперь что касается правил, Они будут иметь те же правила, которые будут применяться к ним. Это будет включать:

Тип ластика Верхний, нижний и неограниченный типы

Кроме того, дженерики могут применяться к отдельным методам. Как и когда вы их используете, зависит от того, что вы пытаетесь сделать.

Для получения дополнительной информации https://www.tutorialspoint.com/java/java_generics.htm

0 голосов
/ 10 января 2019

Вам нужно будет использовать T в определении класса, чтобы подстановочный знак T был привязан к одному и тому же универсальному типу в A и B, разрешая конфликт:

class B<T> extends A<T>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...