2016-12-15 2 views
0

Скажем, у меня определили два класса, Super и Sub и Sub подкласс Super:Каков тип ссылки, поддерживаемой ссылочной переменной суперкласса?

public class Super {} 
public class Sub extends Super {} 

Я знаю, что это законно, чтобы сделать следующее:

Super s = new Sub(); 

Мой вопрос, хотя , что компилятор считает ссылкой в ​​s? Считает ли он, что это просто ссылка типа Super, или он знает, что это на самом деле ссылка типа Sub. Я искал ответы на подобные вопросы, но не нашел ничего определенного. Спасибо!

+1

Компилятор thinka, как супер только – Panther

+1

Нет @Manishsakpal компилятор знает только о типе переменной, которая является супер. Не фактический объект – Panther

+1

Да @panther Я знаю, что компилятор знает только тип переменной Super, но я забыл упомянуть, что во время выполнения это s ссылается на объект типа Sub. Извините моя ошибка. –

ответ

1

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

(Но в выполнении, конечно, виртуальная машина Java будет знать, что экземпляр имеет выполнение типа Sub.)

1

Что вы спрашиваете о том, является ли тип времени выполнения s по сравнению с типом времени компиляции s. Во время компиляции это считается Super, так как это указано в коде. Однако во время выполнения он обрабатывается как Sub.

1

Чтобы ответить на Ваш вопрос, давайте добавим некоторые методы наших классов: -

public class Super { 
     public void superMethod(); 
} 
public class Sub extends Super { 
     public void childMethod(); 
} 

И если сейчас мы попытаемся собрать эти строки ниже: -

Super s = new Sub(); 
s.superMethod(); 
s.childMethod(); 

В коде выше последней строке, не будет компилироваться, поскольку childMethod отсутствует в классе super, но только в Sub. Таким образом, компилятор не компилируется, поскольку ссылается на s как Sub.

1

компилятор думает о нем только как Super.

Рассмотрим:

public class Super {} 
public class Sub extends Super { 
    void f() {} 
} 

Рассмотрим компиляции следующий код:

Super s = new Sub(); 

if (s instanceof Sub) { 
    s.f(); // ERROR: will not compile! 
} 

Несмотря на то, что компилятор может сказать, что тип s проверяется, и в if блоке s должны быть тип Sub (или некоторый потомок), он все равно не будет обрабатывать s как Sub без явного приведения.

Super s = new Sub(); 

if (s instanceof Sub) { 
    ((Sub)s).f(); // Now this compiles. 
} 
Смежные вопросы