class A {
}
class B extends A {
}
A a01 = new A();
A a02 = new B();
Какая разница эта ссылка a02
по сравнению с a01
?
Что означает ссылка на тип class A
или class B
?
Как это работает в памяти?
Нет никакой разницы между a01
и a02
. Оба являются ссылками типа A
Это означает, что вы можете использовать только членов класса A
а не любого из его подтипов.
что означает ссылка класса A или класса B?
Тип ссылки определяется объявлением ссылочной переменной:
A a; // This is a reference of type A
B b; // This is a reference of type B
таково, что если ссылка имеет тип класса А, она автоматически указывает на объект класса А
Да, ссылка типа A
должна указывать на объект типа A
, но также может указывать на любой объект, который имеет подкласс A
для своего типа. В вашем примере B
является A
потому что B extends A
Важно различать объявленный тип переменной и класс среды выполнения объекта.
В Java каждый объект имеет класс выполнения, как указано в выражении создания экземпляра класса (или массива), которое его создало. Время выполнения хранит эту информацию в самом объекте, позволяя нам запрашивать его с помощью оператора instanceof
или getClass()
.
Кроме того, каждая переменная имеет объявленный тип. Объявленные типы используются во время компиляции, чтобы убедиться, что переменные поддерживают операторы, поля и методы, используемые для них кодом. Для этого компилятор и среда выполнения взаимодействуют для обеспечения того, чтобы переменная, объявленная с ссылочным типом D, либо ссылалась на нуль, либо объект, класс выполнения которого D или подтип D во все времена (за исключением нескольких патологических угловых случаев, возникающих из-за неправильного использования общих типов).
В памяти ваш код будет выглядеть примерно так:
+-------+-------+
| a01 | a02 | thread call stack
+-------+-------+
| |
| |
v v
+-----+ +-----+
| A | | B | object heap
+-----+ +-----+
В этом примере Class A является вашим родительским классом, а класс B - это класс, который вы, возможно, знаете, что в основном ваш дочерний класс знает о вашем родительском классе. Но родительский класс не знает, сколько дочерних классов расширило его функциональность. Таким образом, вы можете использовать класс родителя как ссылку на объект дочернего класса, но дочерний класс не может содержать объект родительского класса. В вашем случае оба объекта имеют ссылку на класс A, который не имеет никакого значения. JVM зарезервирует память для объекта в куче и предоставит ссылку в соответствующей ссылке на объект. При компиляции это не имеет никакого значения, но во время выполнения он будет вызывать соответствующий метод объекта.