2016-08-16 3 views
0

У меня есть общий класс A<T>, а подкласс B расширяет A<String>. Класс A имеет метод, который возвращает это значение (так A<T>). Проблема в том, что если я вызову метод на объект B, он вернет A<String>, и мне нужно будет наложить на B, но B - это то же самое, что и A<String>, не так ли? Так что я не должен отбрасывать ...Java generic casting

+0

является 'porsche' то же самое, что и каждый« автомобиль »? – SomeJavaGuy

+1

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

+1

Вам нужен шаблон [return SELF] (https://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current-type-with-a-type-variable) , Это немного уродливо, но работает. Это пример [любопытно повторяющегося шаблона шаблона] (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). –

ответ

1

Если метод возвращает A<String> он может быть объектом типа B, но это не должно быть!

Если у вас есть суперкласс типа car и BMW extends car.

Рассмотрите завод, который создает автомобиль. Метод возвращает автомобиль - это может быть BMW, но он не обязательно должен быть BMW.

+1

Потому что я мог бы создать еще один класс, который также расширяет A , у меня есть только один, поэтому я не видел этого ... – DBLouis

+0

@ L.DUPRÉBERTONI это на самом деле не ответ на вопрос, который имеет хорошее решение. Если я знаю, что у меня есть 'B', а метод в суперклассе возвращает' this', тогда я ожидаю, что он вернет 'B'; но метод действительно вернет 'A '. Путь вокруг этого - любопытно повторяющийся шаблон шаблона. –

+1

@BoristheSpider вопрос был о понимании, почему он должен бросить - я думаю, что я ясно ответил на этот вопрос. Если вы обнаружите, что у вас есть другой вопрос, не стесняйтесь публиковать его в качестве ответа на его вопрос. – Stefan

0

Я переопределил метод и передал возвращаемое значение, чтобы мне не приходилось делать это повсюду. Спасибо @AndyTurner

0

Вам даже не нужно бросать. Вы можете переопределить метод и изменить тип возвращаемого значения B, так как это все еще A<String>, который является A<T>, так что это справедливо для B.

class A<T> { 

    public A<T> return_this() { 
     return this; 
    } 

} 

class B extends A<String> { 

    @Override 
    public B return_this() { 
     return this; 
    } 


} 

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

B b = new B(); 
A<String> a = b.return_this(); //Because B extends A<String> 
B b = b.return_this(); 
+0

Это работает, но становится быстро несостоятельным, если существует большое количество методов. –

+0

Вы можете сделать это, или вы можете бросать каждый раз, когда вы вызываете метод. – germanfr

+0

Как я уже сказал, это зависит. Это решение прост и работает, когда у вас есть один или два метода и один или два класса в иерархии. Это становится недостижимым, если существует большое количество методов, возвращающих типы себя; например, в плане свободного доступа или шаблона построителя. В этом случае требуется любопытно повторяющийся шаблон шаблона. Однако кастинг никогда не является вариантом. –