2013-05-31 4 views
-2

У меня вопрос о литье между базовым классом и его дочерними классами:литье между базовым классом и дочерними классами

(1) Почему это разрешено?

BaseClass b = new ChildClassA(); 
ChildClassA c = (ChildClassA)b 

(2) Почему это запрещено?

ChildClassA c = (ChildClassA)new BaseClass(); 
BaseClass b = (BaseClass)c; 

(3) Почему это разрешено?

BaseClass b = new BaseClass(); 
ChildClassA c = (ChildClassA)c; 

(4) Почему это разрешено?

ChildClassA c = new ChildClassA(); 
BaseClass b = (BaseClass)c; 
+0

Обратите внимание, что (2) * * разрешено компилятором, но вы получите 'InvalidCastException' во время выполнения. –

ответ

4

Причины литого либо допускаются или не допускаются аза за наследованием.

Детский класс (или производный класс) всегда является базовым классом, но противоположное не соответствует действительности.

Для объяснения, давайте использовать некоторые более реальные имена мира для примера классов:

class Animal 
{ 
} 

class Dog : Animal 
{ 
} 

class Cat : Animal 
{ 
} 

Таким образом, для вашего примера (1):

Animal b = new Dog(); 
Dog c = (Dog)b 

Это верно, потому что все собаки являются животные и ваше животное b на самом деле является собакой, поэтому актерский состав успешно завершен.

Для примера (2):

Dog c = (Dog)new Animal(); 
Animal b = (Animal)c; 

Это невозможно, потому что вы назначаете объект животного к собачке, но вы знаете, что не все животные Собака, некоторые животные являются кошки.

А для примеров (3) & (4):

Dog c = new Dog(); 
Animal b = (Animal)c; 

Это то же самое, как ваш пример 1 выше. Все собаки - животные, поэтому любая собака может быть классифицирована как животное и брошена (на самом деле вам не нужна броска, будет неявный бросок, и вы можете записать ее как Animal b = c;

+1

Я не знаю, почему я собирался отредактировать свой ответ, и я тоже хотел использовать пример для собаки. Я думаю, что в мире обучения при программировании в качестве пчелиного пребывания в сексе –

0

Ну ...

(2) не допускается, потому что вы не можете бросить BaseClass к ChildClassA - экземпляр ChildClassA является по наследству также BaseClass, но не наоборот!

0
  1. допускается, потому что б действительно ChildClassA
  2. не допускается, так как вы не можете бросить BaseClass к ChildClass поскольку BaseClass не содержат определение, необходимое для работы ChildClass
  3. допускается, потому что ChildClass содержит все определения для BaseClass и ChildClass IS BaseClass 4.same как 3?
1

(1) Почему это разрешено? BaseClass b = новый ChildClassA(); ChildClassA c = (ChildClassA) b

Потому что ChildClassA является базовым классом.

(2) Почему это запрещено? ChildClassA c = (ChildClassA) new BaseClass(); BaseClass b = (BaseClass) c;

Поскольку BaseClass НЕ ЯВЛЯЕТСЯ ChildClassA

(3) Почему это разрешено? ChildClassA c = new ChildClassA(); BaseClass b = (BaseClass) c;

Потому что ChildClassA является базовым классом.

(4) Почему это разрешено? ChildClassA c = new ChildClassA(); BaseClass b = (BaseClass) c;

То же вопрос 3.

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

Ребенок знает, что относительно его родителя, но родитель не знает, что такое ребенок.

0

Вообще говоря, это потому, что ChildClassA может определять вещи, о которых BaseClass не знает, тогда как, поскольку ChildClassA происходит от BaseClass, он знает все об этом.

1

Подумайте о терминах «есть». Мы можем сказать, что любой экземпляр ChildClassA «является« BaseClass, где class ChildClassA : BaseClass. Но это не так для наоборот. Мы не можем сказать ни одного экземпляра BaseClass «есть» ChildClassA в этом случае

Теперь попробуйте прочитать свои строки кодов следующим образом. На этот раз это будет иметь больше смысла.

new ChildClassA() является экземпляром ChildClassA, затем он также является «BaseClass. Таким образом, мы можем назначить new ChildClassA() к b, который имеет тип BaseClass

Мы можем бросить b к ChildClassA, потому что это на самом деле (точки) в экземпляре ChildClassA.

Мы не можем бросить new BaseClass() к ChildClassA потому что экземпляр BaseClass «не является» ChildClassA

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