Объект, созданный new B()
, может использоваться как объект любого из трех типов - A, B или C. Но вы не можете объявить переменную нескольких типов.
Поскольку B является подтипом A и C, вы можете использовать его экземпляр в качестве экземпляра любого из этих типов. Э.Г.
B o = new B();
A aO = o;
C cO = o;
Теперь вы можете использовать o
для доступа к методам speak
и shutUp
, вы можете использовать aO
для доступа к методу speak
и cO
для доступа к методу shutUp
. Неважно, какую переменную вы будете использовать, вызываемые методы будут одинаковыми, поскольку все эти переменные ссылаются на один и тот же объект. Почему вы не можете использовать aO
для вызова shutUp
в Java, потому что вы объявили переменную с типом, у которого нет такого метода. Хотя вы знаете, что этот конкретный объект имеет этот метод, он вообще не делает его таким.
class D extends A {
public void speak(){
System.out.println("Class D");
}
}
List<A> as = new ArrayList<A>();
as.add(new A());
as.add(new B());
as.add(new D());
A a0 = as.get(0);
A a1 = as.get(1);
A a2 = as.get(2);
a0.speak(); // >> Class A
a1.speak(); // >> Class B
a2.speak(); // >> Class D
Теперь в этом примере у вас есть экземпляры трех разных классов в одной коллекции. Когда вы передаете эту коллекцию или изменяете ее, вы никогда не узнаете, к какому классу относится каждый объект. Все, что вы знаете, это то, что все они относятся к типу A, они гарантированно принадлежат к этому типу, хотя на самом деле они могут быть любого подтипа A (например, B или D).