Здравствуйте, KRA, Вы писали:
KRA>Т.е. нужно привести LA<B> к LA<A>. Этого делать нельзя, это разные типы. KRA>Иначе можно было бы написать такое (на примере List<T>): KRA>
KRA>List<B> b = ...;
KRA>((List<A>)b).add(new A())
KRA>
Здравствуйте, yvad, Вы писали:
Y>Это ограничение только Java или вообще ООП?
Шаблоны/дженерики — это не совсем ООП, точнее совсем не ООП. Это явление скорее следует отнести к взаимодействию ООП и дженериков.
Каково по Вашему мнению разумное поведение в описаной ситуации?
В принципе, можно себе представить вариант, когда приведённый таким способом объект доступен только для чтения... На первый взгляд вроде всё должно работать.
В С++ и .Net такого поведения нет, насколько я знаю и помню.
Здравствуйте, stenkil, Вы писали:
S>Скорее неправильная постановка задачи. Фактически делается попытка привести LB<Integer> к LA<String>
Integer extends String?
Здравствуйте, yvad, Вы писали:
Y>Есть следующая иерархия:
class A {}
class B extends A {}
class LA<T extends A> {}
class LB<T extends B> extends LA<T> {}
Y>Как скастить LB<B> в LA<A>?
Никак, потому что:
class A {}
class B extends A {}
class LA<T extends A> { T t; }
class LB<T extends B> extends LA<T> {}
...
LB<Integer> lbi = new LB<Integer>();
lbi.t = new Integer(0);
LA<Number> lan = (LA<Number>)lbi;
lan.t = new Double(0.0);
assert (lbi.t instanceof Integer);
Ты можешь скастить только в read-only версию, то есть
LB<Integer> lbi = new LB<Integer>();
lbi.t = new Integer(0);
LA<? extends Number> lan = lbi;
lan.t = new Double(0.0); // compile-time error
assert (lbi.t instanceof Integer);
Здравствуйте, techgl, Вы писали:
S>>Скорее неправильная постановка задачи. Фактически делается попытка привести LB<Integer> к LA<String> T>Integer extends String?
A - Object
B extends A - Number
C extends B - Integer
D extends A - String
Вроде все согласно поставленного вопроса. Просто показал что делается попытка привести классы с разными типами, mkizub прекрасно это продемонстрировал, и Java или ООП не виноваты. Jeneric это всего лишь инструкция компилятору.
Здравствуйте, stenkil, Вы писали:
S>Вроде все согласно поставленного вопроса. Просто показал что делается попытка привести классы с разными типами, mkizub прекрасно это продемонстрировал, и Java или ООП не виноваты. Jeneric это всего лишь инструкция компилятору.
Просто не может в качестве примера использоваться Integer и String, они из разных иерархий. Integer и Number — можно.
Здравствуйте, techgl, Вы писали:
T>Просто не может в качестве примера использоваться Integer и String, они из разных иерархий. Integer и Number — можно.
В чем противоречие поставленной задаче? Что такое разные иерархии с точки зрения ООП, ссылку пожалуйста. Наследование или есть или нет.
Здравствуйте, stenkil, Вы писали:
S>В чем противоречие поставленной задаче? Что такое разные иерархии с точки зрения ООП, ссылку пожалуйста. Наследование или есть или нет.
Делается попытка привести не "LB<Integer> к LA<String>", а, напрмиер, LA<Number> к LB<Integer>. Ты указал неправильное объяснение.
M>>class A {}
M>>class B extends A {}
M>>class LA<T extends A> { T t; }
M>>class LB<T extends B> extends LA<T> {}
M>>
Y>Но позволяет LA lan = lbi; Y>Какой в таком случае будет T?
Конкретно в этом коде — T будет A.
Я ошибся когда писал, потому как LA<Integer> писать нельзя было, так как Integer не extends A.
Ява позволяет это делать для обратной совместимости, и в байткоде генерируется class LA { A t; } и LB extends LA {}
А информация <T extends B> в байткоде никак не отображена (забыта). А для доступа к lbi.t будет везде сгенерирован каст ((B)lbi.t), который и может сработать если сделать LA lan = lbi; lan.t = new A(); B b = lbi.t;
Здравствуйте, mkizub, Вы писали:
M>Здравствуйте, yvad, Вы писали:
M>>>
M>>>class A {}
M>>>class B extends A {}
M>>>class LA<T extends A> { T t; }
M>>>class LB<T extends B> extends LA<T> {}
M>>>
Y>>Но позволяет LA lan = lbi; Y>>Какой в таком случае будет T?
M>Конкретно в этом коде — T будет A. M>Я ошибся когда писал, потому как LA<Integer> писать нельзя было, так как Integer не extends A.
M>Ява позволяет это делать для обратной совместимости, и в байткоде генерируется class LA { A t; } и LB extends LA {} M>А информация <T extends B> в байткоде никак не отображена (забыта). А для доступа к lbi.t будет везде сгенерирован каст ((B)lbi.t), который и может сработать если сделать LA lan = lbi; lan.t = new A(); B b = lbi.t;
Тогда мне подходит.
Только смущает, что нельзя почему-то написать LA<A> lan = lbi;