Я предполагаю, судя по названию, что код на самом деле должен был быть b2.subtract()
. Идем с этим:
Хотя b2 в настоящее время является экземпляром Child, и довольно легко увидеть, что в вашем коде это всегда будет экземпляр Child, Java статически типизирована и поэтому не может позволить вам использовать методы фактического класс, просто объявленный класс.
Рассмотрим этот пример:
Base b2 = Math.random() > 0.5 ? new Base() : new Child();
b2.subtract();
Теперь невозможно сказать во время компиляции, какой экземпляр b2 на самом деле будет экземпляром, поэтому вы, очевидно, не можете вызывать какие-либо методы в Child (поскольку b2 может быть просто Base!). Не было бы никакого смысла в том, чтобы быть исключением из этого для случаев, подобных вашему примеру, так как это могло бы вызвать lot путаницы, и эти случаи можно легко исправить, чтобы они работали как есть изменение объявленного типа на дочерний, а не базовый).