Непонятки с синтаксисом
От: yvad  
Дата: 27.11.08 18:00
Оценка:
Есть следующая иерархия:

class A {}
class B extends A {}
    
class LA<T extends A> {}
class LB<T extends B> extends LA<T> {}


Как скастить LB<B> в LA<A>?

LB<B> lb = new LB<B>();
LA<A> la = (LA<A>)lb;
Re: Непонятки с синтаксисом
От: KRA Украина  
Дата: 27.11.08 19:00
Оценка:
Здравствуйте, yvad, Вы писали:

Y>Есть следующая иерархия:


Y>
Y>class A {}
Y>class B extends A {}
    
Y>class LA<T extends A> {}
Y>class LB<T extends B> extends LA<T> {}

Y>


Y>Как скастить LB<B> в LA<A>?


Y>
Y>LB<B> lb = new LB<B>();
Y>LA<A> la = (LA<A>)lb;

Y>


Т.е. нужно привести LA<B> к LA<A>. Этого делать нельзя, это разные типы.
Иначе можно было бы написать такое (на примере List<T>):
List<B> b = ...;

((List<A>)b).add(new A())


А это ясно, что небезопасно.
Re[2]: Непонятки с синтаксисом
От: yvad  
Дата: 27.11.08 19:03
Оценка:
Здравствуйте, KRA, Вы писали:

KRA>Т.е. нужно привести LA<B> к LA<A>. Этого делать нельзя, это разные типы.

KRA>Иначе можно было бы написать такое (на примере List<T>):
KRA>
KRA>List<B> b = ...;

KRA>((List<A>)b).add(new A())
KRA>


KRA>А это ясно, что небезопасно.


Это ограничение только Java или вообще ООП?
Re[3]: Непонятки с синтаксисом
От: KRA Украина  
Дата: 27.11.08 19:18
Оценка:
Здравствуйте, yvad, Вы писали:

Y>Это ограничение только Java или вообще ООП?


Шаблоны/дженерики — это не совсем ООП, точнее совсем не ООП. Это явление скорее следует отнести к взаимодействию ООП и дженериков.
Каково по Вашему мнению разумное поведение в описаной ситуации?
В принципе, можно себе представить вариант, когда приведённый таким способом объект доступен только для чтения... На первый взгляд вроде всё должно работать.
В С++ и .Net такого поведения нет, насколько я знаю и помню.
Re: Непонятки с синтаксисом
От: AutumnLeaf Великобритания  
Дата: 28.11.08 06:07
Оценка:
Здравствуйте, yvad, Вы писали:

Y>Есть следующая иерархия:


Y>
Y>class A {}
Y>class B extends A {}
    
Y>class LA<T extends A> {}
Y>class LB<T extends B> extends LA<T> {}

Y>


Y>Как скастить LB<B> в LA<A>?


Y>
Y>LB<B> lb = new LB<B>();
Y>LA<A> la = (LA<A>)lb;

Y>


LB<B> lb = new LB<B>();
LA<A> la = (LA<A>) (List) lb;
Re[3]: Непонятки с синтаксисом
От: stenkil  
Дата: 28.11.08 08:06
Оценка:
Здравствуйте, yvad, Вы писали:

Y>Это ограничение только Java или вообще ООП?


Скорее неправильная постановка задачи. Фактически делается попытка привести LB<Integer> к LA<String>
Re[4]: Непонятки с синтаксисом
От: techgl  
Дата: 28.11.08 08:41
Оценка:
Здравствуйте, stenkil, Вы писали:

S>Скорее неправильная постановка задачи. Фактически делается попытка привести LB<Integer> к LA<String>

Integer extends String?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Непонятки с синтаксисом
От: mkizub Литва http://symade.tigris.org
Дата: 28.11.08 09:26
Оценка: 1 (1)
Здравствуйте, 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);


тогда это будет type safe.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[5]: Непонятки с синтаксисом
От: stenkil  
Дата: 28.11.08 10:59
Оценка:
Здравствуйте, 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 это всего лишь инструкция компилятору.
Re[6]: Непонятки с синтаксисом
От: techgl  
Дата: 28.11.08 11:28
Оценка:
Здравствуйте, stenkil, Вы писали:

S>Вроде все согласно поставленного вопроса. Просто показал что делается попытка привести классы с разными типами, mkizub прекрасно это продемонстрировал, и Java или ООП не виноваты. Jeneric это всего лишь инструкция компилятору.

Просто не может в качестве примера использоваться Integer и String, они из разных иерархий. Integer и Number — можно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Непонятки с синтаксисом
От: stenkil  
Дата: 28.11.08 11:38
Оценка:
Здравствуйте, techgl, Вы писали:

T>Просто не может в качестве примера использоваться Integer и String, они из разных иерархий. Integer и Number — можно.


В чем противоречие поставленной задаче? Что такое разные иерархии с точки зрения ООП, ссылку пожалуйста. Наследование или есть или нет.
Re[8]: Непонятки с синтаксисом
От: techgl  
Дата: 28.11.08 12:12
Оценка:
Здравствуйте, stenkil, Вы писали:

S>В чем противоречие поставленной задаче? Что такое разные иерархии с точки зрения ООП, ссылку пожалуйста. Наследование или есть или нет.

Делается попытка привести не "LB<Integer> к LA<String>", а, напрмиер, LA<Number> к LB<Integer>. Ты указал неправильное объяснение.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Непонятки с синтаксисом
От: yvad  
Дата: 29.11.08 14:22
Оценка:
Здравствуйте, mkizub, Вы писали:

M>Никак, потому что:


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>...
M>LB<Integer> lbi = new LB<Integer>();
M>lbi.t = new Integer(0);
M>LA<Number> lan = (LA<Number>)lbi;
M>lan.t = new Double(0.0);

M>assert (lbi.t instanceof Integer);
M>


M>Ты можешь скастить только в read-only версию, то есть


M>
M>LB<Integer> lbi = new LB<Integer>();
M>lbi.t = new Integer(0);
M>LA<? extends Number> lan = lbi;
M>lan.t = new Double(0.0); // compile-time error

M>assert (lbi.t instanceof Integer);
M>


M>тогда это будет type safe.


Но позволяет LA lan = lbi;
Какой в таком случае будет T?
Re[3]: Непонятки с синтаксисом
От: mkizub Литва http://symade.tigris.org
Дата: 29.11.08 15:11
Оценка:
Здравствуйте, 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?

Конкретно в этом коде — 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;
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[4]: Непонятки с синтаксисом
От: yvad  
Дата: 29.11.08 15:31
Оценка:
Здравствуйте, 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;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.