Присвоение дочернего объекта родительскому объекту

Я работаю ниже кода Java и не могу понять, почему он возвращает 0 в качестве вывода вместо 200 или 500.

class Bike{
  int speedlimit;
 }
 class Honda3 extends Bike{
  int speedlimit;
 
  public static void main(String args[]){
   Bike obj=new Bike();
   obj.speedlimit=200;
   Honda3 obj2=new Honda3();
   obj2.speedlimit=500;
   obj=obj2;
  System.out.println(obj.speedlimit);
 }
}

Выход: 0

  1. Я думаю, что obj=obj2 будет работать как полиморфизм во время выполнения, но кажется, что мои рассуждения неверны. Не уверен, что мне здесь не хватает.
  2. Я сам раньше не использовал код типа obj=obj2 и подумал, есть ли сценарий, в котором он может быть полезен?
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
287
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы видите 0, потому что вы используете два отдельных атрибута ограничения скорости, один для класса Bike, а другой для класса Honda3, вы можете просто удалить атрибут из класса Honda3, потому что он наследует его от класса Bike.

В этой строке obj.speedlimit вы присваиваете атрибут Bike, а в другой руке obj2.speedlimit присваиваете атрибут Honda3. Когда вы назначаете obj = obj2, а затем получаете доступ к атрибуту ограничения скорости из obj, вы больше не используете атрибут класса Honda3, а атрибут класса Bike, который еще не был назначен.

Если вы удалите атрибут ограничения скорости из класса Honda3, ваша проблема исчезнет.

Когда вы определяете поле в подклассе, которое имеет то же имя, что и поле в суперклассе, вы не переопределяете поле, а только «скрываете» его для пользователей подкласса.

Таким образом, когда вы создаете Honda3, вы создаете объект с двумя полями ограничения скорости: поле класса Bike инициализируется нулем (поскольку это значение по умолчанию для целых чисел), а поле класса Honda3 устанавливается равным 200. Затем, когда вы " используйте Honda3 как «Велосипед», поле ограничения скорости для класса «Велосипед» больше не скрыто и распечатывается по стандарту.

Потому что obj2 = obj назначает экземпляр Honda3 со скрытым полем Bike.speedlimit, которое по умолчанию инициализируется 0

  1. new Bike() с speedlimit переменной экземпляра 0 создается, а затем назначается 200

  2. new Honda3() создается с переменной экземпляра speedlimit = 0 и Bike.speedlimit = 0, который наследуется от Bike, тогда speedlimit присваивается 500. Honda3 скрывает Bikespeedlimit

Когда вы присваиваете obj = obj2, вы выполняете приведение вверх и ссылаетесь на Honda как на Bike, а System.out.prinln(obj.speedlimit) печатает Bike.speedlimit, наоборот, если бы вы делали понижающее приведение System.out.println(((Honda3) obj).speedlimit), вы получили бы 500

Также полиморфизм времени выполнения или динамическая диспетчеризация работают только для методов, а не для элементов данных. Методы переопределяются, но поля скрыты.

После obj = obj2

Ответ принят как подходящий

Когда вы создаете объект Honda3, созданный объект также включает в себя все поля родительского класса, то есть Bike. Все поля инициализируются значением по умолчанию (speedlimit = 0). Также при создании объекта мы не можем отбросить поле speedlimit велосипеда только потому, что Honda3 имеет поле с таким же именем. Мы не говорим компилятору переопределить поле, поэтому компилятор будет включать оба поля speedlimit внутри объекта Honda3, как это:

  • ограничение скорости (от велосипеда) <= скрыто
  • Ограничение скорости

Итак, если вы присваиваете объект Honda3 переменной типа Bike, вы можете получить доступ к скрытому speedlimit через эту переменную. Пожалуйста, обратитесь к изображению ниже, чтобы визуализировать весь процесс.

Другие вопросы по теме