2016-10-17 3 views
1

Я пытаюсь определить, а затем реализовать абстрактный сеттер, который принимает список объектов в качестве параметра. Вот суть этой простой идеи:Реализовать общий метод со значением параметра списка

public abstract class MyClass { 
    public abstract void setThings(List<?> things); 
} 

public class Bar extends MyClass { 
    private List<String> things; 

    @Override 
    public void setThings(List<String> things) { 
     this.things = things; 
    } 
} 

Это не работает. Я получаю Method does not override method from its superclass и both methods have the same erasure, but neither overrides the other. Я понимаю последнюю ошибку, связанную с стираниями, но даже не могу понять, как это сделать. Я пробовал некоторые другие:

public abstract <T> void setThings(List<T> things); 

... а также несколько других. И я нашел другие вопросы/ответы на SO, которые приблизились к решению этого вопроса, но никто из них не предоставил надежного ответа (по крайней мере, это не было ясно для меня). Я прочитал the tutorials, но безрезультатно. Что мне не хватает?

ответ

3

Итак, Java вполне правильно говорит вам, что вы не внедрили абстрактный метод setThings, который принимает List<?> не List<T> или List<String>. Все это разные вещи. См. this question for a detailed explanation.

Самое простое решение ввести общий для абстрактного класса, а также:

public abstract class MyClass<T> { 
    public abstract void setThings(List<T> things); 
} 

public class SubClass extends MyClass<String> { 
    private List<String> things; 

    public void setThings(List<String> things) { 
     this.things = things; 
    } 
} 
+0

Спасибо, я пошел с вашим примером, и он работает красиво. Мне придется потратить еще некоторое время на изучение дженериков, некоторые из тонкостей по-прежнему немного таинственны для меня, такие как разница между использованием '?', 'T',' E 'и т. Д. Ничего лишнего (более) чтения не может исправить! – Madbreaks

2

List<?> things - это список неизвестного типа.

List<T> things - это список типов T.

Эти две вещи не то же самое, поэтому вы получаете эту ошибку компиляции.

Есть несколько разумных путей искоренения ошибки:

  • Generify оба класса

    abstract class MyClass<T> { 
        public abstract void setThings(List<T> things); 
    } 
    
    class Bar<T> extends MyClass<T> { 
        private List<T> things; 
    
        @Override 
        public void setThings(List<T> things) { 
         this.things = things; 
        } 
    } 
    
  • Сделать Bar принимает список неизвестного типа, а

    abstract class MyClass { 
        public abstract void setThings(List<?> things); 
    } 
    
    class Bar extends MyClass { 
        private List<?> things; 
    
        @Override 
        public void setThings(List<?> things) { 
         this.things = things; 
        } 
    } 
    
+0

К сожалению, я просто забыл 'модификатор abstract' класса в моем примере, но у меня есть, что в моем фактическом коде. Я обновил вопрос, чтобы отразить это. Однако мне нужен конкретный тип в моем подклассе. – Madbreaks

Смежные вопросы