Java-кастинг со ссылкой на суперкласс - PullRequest
5 голосов
/ 22 ноября 2011

Может кто-нибудь объяснить, что здесь происходит?

Предположим, Car и Bike являются подклассами Vehicle.

Мне кажется, что Vehicle v ссылка передается наBike.Я знаю, что это незаконно, и действительно, компилятор выплевывает ... Car cannot be cast to Bike.

Но разве это не должно быть Vehicle, не может быть приведено к Bike?В конце концов, Vehicle v является ссылкой Vehicle.

public class Test {
   public static void main(String[] args) {
       Vehicle v = new Car();
       Bike b = (Bike) v;
       // some stuff
    }   
}

Ответы [ 5 ]

3 голосов
/ 22 ноября 2011

Сообщение об ошибке гласит Car, потому что это исключение времени выполнения.Поскольку к этому времени он знает фактический экземпляр (Car, Bike или Vehicle), на который указывает ссылка Vehicle, он выдает более конкретное сообщение об ошибке.

Если во время компиляции это исключение, компилятор упомянулVehicle, поскольку компилятор может не знать фактический экземпляр, на который указывает ссылка Vehicle.

1 голос
/ 22 ноября 2011

Это на самом деле Car, который разыгрывается. v имеет тип Vehicle, поэтому назначение Vehicle v = new Car(); работает, поскольку Car является Vehicle.

Объект v сохраняет свою идентичность; это быть Car. Таким образом, нелегальный актерский состав от Car до Bike.

0 голосов
/ 22 ноября 2011

Без исходного кода невозможно однозначно сказать, что законно, а что нет. Однако можно с уверенностью предположить, что дерево наследования для этих классов выглядит примерно так:

    Vehicle
       |
  __________
  |         |
 Car      Bike

Так что Car и Bike являются подклассами Vehicle, что означает, что Vehicle является обобщением Car и Bike. В Java вы можете преобразовать экземпляр подкласса в его базовый класс. Таким образом, в этом случае вы можете наложить Car на транспортное средство и обращаться с ним так, как будто у вас есть экземпляр объекта Vehicle. То же самое относится и к Bike. Однако, поскольку Car не является подклассом Bike, вы не можете разыгрывать одно из другого. Все Cars являются Vehicles, но не все Vehicles являются Cars. И при этом они Bikes. И Car никогда не будет Bike и наоборот.

Вы делаете это для создания более расширяемого кода. Например, вы можете написать код, который понимает, как взаимодействовать с кодом, который будет написан в будущем. Примером этого может быть некоторый общий интерфейс, такой как drive(), который позволяет другим разработчикам предоставлять пользовательские реализации позже. Ваш код, написанный ранее, может работать с ним, потому что он может обрабатывать новые подклассы, как если бы они были экземплярами базового класса.

0 голосов
/ 22 ноября 2011

A (полу) простой английский ответ:

Автомобиль не может внезапно «стать» байком или рассматриваться как мотоцикл, потому что у велосипеда будут разные свойства (переменные) , описывающие его, и различные способы взаимодействия с это (методы).

Однако оба они являются транспортными средствами, поэтому у них есть некоторые общие черты, такие как, например, способность управлять, поворачивать влево или вправо или переключать передачи.

Это упрощает, когда у вас есть такая логика:

ArrayList<Vehicle> vehicles = new ArrayList<Vehicle>();
vehicles.add(new Bike());
vehicles.add(new Car());
vehicles.add(new Bike());

//Some other crazy code

for(Vehicle v : vehicles) {
    v.applyBrakes();
    v.changeDownGear();
    v.turnRight();
}

каждый подкласс Vehicle (Bike, Car, Segway и т. Д.) Будет иметь собственную реализацию этих методов и будет обрабатывать себя соответствующим образом

0 голосов
/ 22 ноября 2011

Линия

Bike b = (Bike) v;

было бы законно, если бы, скажем, v было передано Vehicle. Поэтому я бы предположил, что эта проверка происходит в процессе оптимизации. Компилятор хочет оптимизировать обычную работу при приведении, если он может - возможно, даже оптимизировать b в целом - и, конечно, может , если v был создан как Bike на предыдущем строка вместо Car.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...