2013-11-28 4 views
4

В следующем кодеКастинг между интерфейсом sublass и суперкласса, когда суперкласс не реализует интерфейс, но подкласс

abstract class Vehicle { } 
class Car extends Vehicle implements LandMover { } 
interface LandMover { } 
    Car porsche=new Car(); 
    LandMover lmv; 
    lmv = porsche; 
    Vehicle vec = (Vehicle)lmv; 

не должно там быть ошибка компилятора в 4-й строке, поскольку нет никакой связи между класса автомобиля и интерфейса LandMover? ? и если нет, то что может быть причиной. Спасибо!

+0

Что случилось, когда вы попробовали? –

+0

@ Kugathasan Я попробовал, он не показывает какую-либо ошибку компиляции, и я немного смущен теперь с ответом – unknown

ответ

6

Компилятор только проверяет, есть ли возможная связь, и есть один:

LandMover может быть Car, который, в свою очередь, IS-A Vehicle. Поскольку вы обещаете, что это преобразование в порядке, используя явное приведение, компилятор счастлив.

+0

Хорошо спасибо за инициативу ура и ответ :) – unknown

-1

будет ошибка как абстрактный класс не может быть создан больше относятся к этому post

+0

, но я havent экземпляр абстрактного класса ... – unknown

+0

он не создавал абстрактный класс. он создал экземпляр подкласса и использовал переменную суперкласса для хранения ссылки. – latenightcode

0

При явном нажатии на Vehicle компилятор ничего не скажет. Вы можете просто получить исключение во время выполнения, если отношения, наконец, не совсем работать, и вы бросаете что-то, что на самом деле не Vehicle

1

Нет, так как

LandMover lmv = porsche; 

не объявляет объект тип LandMover, но относится к объекту типа «Автомобиль» по ссылке «LandMover». Компилятор знает, что это объект типа «Автомобиль» (примечание: «Автомобиль» и «Vehicale» находятся в одном дереве наследования).

0

Компиляция будет в порядке с кодом, который вы предоставили. lmv = porsche; - это то же самое, что и слова

public class Car extends Vehicle implements LandMover { 

    public static void main(String args[]){ 

     LandMover car = new Car(); 
    } 
} 

Автомобиль реализует LandMover, так что вы можете использовать его в качестве полиморфных ссылки. так что никаких проблем до сих пор.

Vehicle vec = (Vehicle)lmv; 

Теперь вы говорите, что LandMover (ссылка), которая может очень хорошо быть автомобиль является фактом транспортного средства. Поэтому компилятор не будет жаловаться.

Но обратите внимание, что если вы попробуете вызвать какую-либо функцию на vec, которая не определена в классе автомобиля (даже в классе автомобилей, хотя это не экземпляр класса авто), компилятор будет жаловаться.

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

0

Ошибок компиляции не будет. Это связано с тем, что класс может реализовать множество интерфейсов, поэтому данный экземпляр «LandMover» может быть транспортным средством. Однако, поскольку класс может наследовать один суперкласс, вы знаете, что вы не можете наложить «java.lang.String» на «Vehicle», потому что у них нет общего суперкласса, отличного от объекта.

0

Учитывая иерархию

Car extends Vehicle

&

Car implements LandMover

для литья Vehicle vec = (Vehicle)lmv; компилятор может проверить статически (время компиляции), тип lmv который LandMover и которые, в свою очередь, также CAN be Car (как Car implements LandMover). Теперь как Car extends Vehicle компилятор не жалуется.

для подтверждения, попробуйте комментируя код следующим

 //Car porsche=new Car(); 
     LandMover lmv; 
     //lmv= porsche; 
     Vehicle vec = (Vehicle)lmv; //Compiler error 

Здесь компилятор уверен, что lmvНЕ МОЖЕТ бытьVehicle наверняка и, следовательно, флагов ошибок.

+1

компиляция не выполняется из-за того, что 'lmv' не инициализируется, если u set lmv = null, он компилируется нормально. –

+0

Это даст исключение во время выполнения (исключение класса cast), оно компилируется отлично, потому что компилятор считает, что существует возможность того, что автомобиль абстрактного класса расширяется другим классом, и поскольку kappil дал объяснение выше, истечение срока литья не даст никакой ошибки компиляции – unknown

+0

@DevBlanked thanks для указания этого. – Santosh

Смежные вопросы