Здесь возникают две проблемы: тип переменной или выражения и класс объекта.
У каждого объекта есть класс, который устанавливается при его создании с помощью "new" или clone(). Этот класс фиксируется на время жизни объекта.
Ссылочная переменная или выражение либо имеют значение null, либо являются указателем на некоторый объект. Тип ссылочной переменной указывается именем класса или интерфейса. Он может ссылаться на объект только в том случае, если класс объекта соответствует или расширяет, прямо или косвенно, класс или реализует интерфейс. По сути, тип переменной гарантирует, что у объекта есть соответствующие члены.
A a = new A(); //statement 1
Объявляет переменную "a" с типом A, что означает, что она может быть только нулевой или указателем на A, или объектом, класс которого расширяет A. Инициализирует ее как указатель на вновь созданный объект класса A.
A a1= new B(); //statement 2
Объявляет переменную "a1" с типом A, что означает, что она может быть только нулевой или указателем на A, или объектом, класс которого расширяет A. Инициализирует его указателем на вновь созданный B. Поскольку B расширяет A, преобразование выражение типа B для типа A разрешено.
B b= (B) new A(); // statement 3
Разница здесь в том, что A не расширяет B. Ссылка типа A может быть приведена к типу B тогда и только тогда, когда она является нулевой или указателем на объект класса B или класс, который расширяет B. Класс A не не расширять B. Компилятор примет это, потому что приведение утверждает, что "new A()" имеет значение null или ссылается на объект класса B или объект класса, расширяющий B. Он получит ClassCastException во время выполнения, потому что это утверждение ложно.
Тип ссылочной переменной или выражения определяется во время компиляции. В ходе выполнения программы он может быть нулевым или ссылаться на объекты нескольких разных классов, но только на те классы, которые соответствуют его объявленному типу.
person
Patricia Shanahan
schedule
08.09.2013