2015-08-02 3 views
1

Я делаю опыт, пытаясь переопределить метод родового класса, таким образом:Java Generic Class Метод Перекрытие

public class MyGenFun<T extends CharSequence> extends Do<String>{ 
    public void doX(T s){ 
     System.out.println("in CHILD"); 
    } 

    public static void main (String ...a){ 
     MyGenFun<String> x = new MyGenFun<>(); 
     x.doX("Test"); /// LINE 1 
    } 
} 

class Do<A>{ 

    public void doX(A a){ 
     System.out.println("in Super"); 
    } 
} 

Почему я не могу? Ошибка компиляции

yGenFun.java:15: error: reference to doX is ambiguous, both method doX(A) in Do and method doX(T) in MyGenFun match x.doX("Test"); ^ where A,T are type-variables: A extends Object declared in class Do T extends CharSequence declared in class MyGenFun 1 error

Если я прокомментирую «Линия 1», я могу скомпилировать код. Поэтому я считаю, что я правильно отношусь.

ответ

4

Это потому, что вы не фактически отменяя метод, но только перегрузки это. Для переопределения все типы аргументов должны совпадать. Таким образом, правильный метод коррекции будет

public void doX(String s) {  
} 

T является то, что расширяет CharSequence, который может быть String, но не нужно быть String, это может быть, например, CharBuffer, а также.

Вы инстанцируете следующее:

MyGenFun<String> x = new MyGenFun<>(); 

Итак, потому что вы не перекрывая этот метод, но перегружать его, в настоящее время существует два метода с той же подписью в текущем контексте, один приходит из класса ребенка, один от высшего класса:

public void doX(String a) { 
... 
} 
+0

Тип-стирание не стирает doX (T) до doX (Object) как в супер, так и в child и становится Override? –

+0

Компилятор по-прежнему проверяет использование дженериков перед генерированием типов байт-кода и стирания. См. [Link] (http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens) – beosign

3

Имея эту иерархию классов, у вас есть два перегруженных методов с подписями:

public void doX(String s){ 

} 

public void doX(CharSequence s){ 

} 

При передаче String в doX, компилятор не может сделать вывод, какой из двух методов для вызова, потому что String совместим с String и CharSequence в то же время.

Таким образом, вы должны скорее переопределить так:

public class MyGenFun<T extends CharSequence> extends Do<T>{ 

    @Override 
    public void doX(T s){ 
     System.out.println("in CHILD"); 
    } 
} 
+0

@ThufirHawat, проверьте мое обновление. –

+0

Спасибо за ответ. Но я не могу понять, почему этот метод был перегружен. Тип-стирание не стирает общий и по методам только Object? И чем, я получаю метод Override, когда оба выполняются (Object)? –

+0

Компилятор по-прежнему проверяет использование дженериков перед генерированием типов байт-кода и стирания: см. Http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens – beosign

0

ваш метод подписи говорит, что вам нужен параметр, чтобы передать, общественности недействительным DOX (T s);

so call like : x.doX("abc");