Без исходного кода невозможно однозначно сказать, что законно, а что нет. Однако можно с уверенностью предположить, что дерево наследования для этих классов выглядит примерно так:
Vehicle
|
__________
| |
Car Bike
Так что Car
и Bike
являются подклассами Vehicle
, что означает, что Vehicle
является обобщением Car
и Bike
. В Java вы можете преобразовать экземпляр подкласса в его базовый класс. Таким образом, в этом случае вы можете наложить Car
на транспортное средство и обращаться с ним так, как будто у вас есть экземпляр объекта Vehicle
. То же самое относится и к Bike
. Однако, поскольку Car
не является подклассом Bike
, вы не можете разыгрывать одно из другого. Все Cars
являются Vehicles
, но не все Vehicles
являются Cars
. И при этом они Bikes
. И Car
никогда не будет Bike
и наоборот.
Вы делаете это для создания более расширяемого кода. Например, вы можете написать код, который понимает, как взаимодействовать с кодом, который будет написан в будущем. Примером этого может быть некоторый общий интерфейс, такой как drive()
, который позволяет другим разработчикам предоставлять пользовательские реализации позже. Ваш код, написанный ранее, может работать с ним, потому что он может обрабатывать новые подклассы, как если бы они были экземплярами базового класса.