Что происходит, когда объекту подкласса присваивается статус объекта суперкласса

#java #oop #inheritance #polymorphism

#java #ооп #наследование #полиморфизм

Вопрос:

Итак, у меня есть вопрос о суперклассе A и подклассе B, где A имеет 2 общедоступные переменные, а B имеет еще 1.

Я видел этот фрагмент кода:

 A a = new A();
B b = new B();
a = b; 
  

Что делает эта последняя строка? Я не совсем понимаю, что на самом деле происходит, когда вы используете «=» между двумя классами в отношениях наследования.

Комментарии:

1. Что бы он делал, если бы вместо этого у вас был int x = 0; int y = 1; x = y; ?

2. Объекты не назначаются. Назначаются ссылки.

Ответ №1:

Это простое присвоение. = является оператором присваивания.

Давайте проясним нижеприведенные моменты.

  1. В Java, когда объект создается и он доступен через. ссылка. Ссылка ссылается на объект.
  2. Одновременно одна ссылка может ссылаться только на один объект
  3. Ссылка типа X может ссылаться на объект типа X или любые подтипы (расширяющиеся в случае, если X является классом, или реализующие, если X является интерфейсом).

Теперь предположим, что существуют два класса Super и Sub такие, что Sub extends Super .

  SuperClass reference = new SubClass();  
  

Это разрешено, поскольку подкласс наследуется от суперкласса.
Выше у нас есть объект типа SubClass, созданный в куче, и он доступен через . ссылка с именем reference

Обратите внимание, что ссылка типа SubClass не может ссылаться на object of SuperClass . Давайте вкратце разберемся, почему это так?. Если бы ссылке типа SubClass было разрешено ссылаться на объект типа SuperClass , тогда было бы разрешено вызывать дополнительные методы (функции), определенные SubClass ( SubClass унаследовали бы все методы SuperClass , а также определили бы несколько дополнительных методов). Теперь это привело бы к аварийному завершению работы приложения, поскольку объект SuperClass имеет только методы, определенные в SuperClass , но не имеет никаких дополнительных методов, определенных SubClass . Следовательно, компилятор предотвращает это во время компиляции. Наличие ссылки типа SubClass , ссылающейся на объект типа, является ошибкой времени компиляции SuperClass

Теперь давайте посмотрим на код, упомянутый в вопросе

  SuperClass a = new SuperClass();
 SubClass b = new SubClass();
 a = b; 
  

Строка 1: У нас есть объект суперкласса, на который ссылается переменная типа SuperClass с именем a

Строка 2: У нас есть объект подкласса, на который ссылается переменная типа SubClass с именем b

Строка 3: У нас есть назначение, в котором a назначается ссылка на тот же объект, на который ссылается b . Итак, теперь у нас есть обе ссылки, ссылающиеся на объект типа, SubClass созданный в строке 2. Объект типа typer, SuperClass созданный в строке 1 (с текущим доступным кодом, упомянутым в вопросе), не имеет никаких ссылок, поэтому он подходит для сборки мусора.

Комментарии:

1. Большое вам спасибо! теперь все намного яснее. Итак, если бы вместо этого у нас было «b = a» (в строке 3), это привело бы к ошибке времени выполнения / компиляции? поскольку переменная типа SubClass не может ссылаться на объект суперкласса?

2. @din abarbanel да, это верно, я отредактировал свой ответ, чтобы включить объяснение и для этого. Надеюсь, это будет полезно для вас

Ответ №2:

Ничего «не происходит». Объект, на который ссылается переменная ‘b’, является единственным объектом. Это одновременно экземпляр B и экземпляр A.

При выполнении присвоения a = b объект, на который ранее ссылалась переменная ‘a’, становится недоступным. Соображения об этом старом объекте не входят в это обсуждение.

После присвоения ‘a’ и ‘b’ относятся к одному и тому же объекту. Объект не изменился. Это все еще экземпляр B и экземпляр A.

Возможно, блок в вашем понимании — это различие между объектами и переменными, которые ссылаются на эти объекты?