2014-02-16 4 views
6

я нашел следующий вопрос в моем исследовании книги и немного запутался:Java отливку объект интерфейса, который не реализован

Учитывая следующий код, какой вариант, если используется для замены /* INSERT CODE HERE */, даст возможность ссылочную переменную типа Roamable для ссылки на объект класса Phone? (Выберите 1 вариант.)

interface Roamable{} 
class Phone {} 
class Tablet extends Phone implements Roamable { 
    //INSERT CODE HERE 
} 

Варианты:

  1. Roamable var = new Phone();
  2. Roamable var = (Roamable)Phone();
  3. Roamable var = (Roamable)new Phone();
  4. Поскольку интерфейс Roamable и класс Phone не имеют никакого отношения, ссылка переменной типа Roamable не может относиться к объекту класса Phone ,

Я думал, что правильный вариант 4, однако он говорит, что это 3.

Но Phone не реализует Roamable интерфейс, так что вы не можете бросить, не так ли?

+1

Ну, вы попробуете это? Что вы узнали после тестирования? – Zavior

+0

Справа. Попробуйте и посмотрите, что произойдет. –

ответ

1

Ответ будет

в

1 is incorrect(explanation --> 4) 
2 is incorrect syntax 
3 is incorrect typecast. 

Обратите внимание, что ответ 3 действует до тех пор, как это только о компиляции. Когда вы говорите, что у вас есть экземпляр класса Phone, вы можете ввести букву в Tablet (Аналогично тому, как вы можете наложить Object на String). И так как Tablet реализует Roamable, вы можете очень хорошо использовать ссылку Roamable для ссылки. Problem will occur at runtime как Object действительно типа Phone.

Это всего лишь один из связующих звеньев (в текущем контексте), который позволяет успешно компилировать. Но, как Bohemian упомянули в своем ответе вообще

Если мы типажи время компиляции ссылка S (не окончательная) компилировать отсчет время T, то компиляция будет успешным, как even if S does not implement T, a subclass of S might. Если S - конечный класс, то S должен реализовать T, или возникает ошибка времени компиляции.

На самом деле нет необходимости в Tablet классе, распространяющемся на Phone класс вообще.До тех пор, как телефон класс not final компиляции будет успешной

interface Roamable{} 
class Phone {} 
class Tablet implements Roamable { 
    Roamable var = (Roamable)new Phone(); // Compiles 
} 
+0

Просто, чтобы вы знали, ваше объяснение совершенно неверно, и ваш пример литья не имеет значения. – Bohemian

+0

Да, вы правы. Ректифицированный. Благодарю. –

+0

Вы также должны ознакомиться с [определение плагиата] (http://dictionary.reference.com/browse/plagiarism) :) – Bohemian

10

Правильный ответ 3: компилятор видит только то, что Phone является преобразовывается к Roamable и Phone не является окончательным, поэтому считает, что объект будучи обозначенным как Phone, может быть подклассом Phone, который выполняет, реализует Roamable, поэтому не возникает ошибка или предупреждение об ошибке компиляции.

Согласно JLS chapter 5

5.5.1. Литье

Тип ссылки Учитывая время компиляции ссылочного типа S (источник) и ссылки во время компиляции типа Т (мишень), преобразование литья существует с S к Т, если никаких ошибок времени компиляции не происходят из-за следующие правила. Если T - тип интерфейса:

Если S не является окончательным классом (§8.1.1), то, если существует супертип X из T и супертип Y из S, такой, что и X, и Y являются явно различимыми параметризованными типами и что стирания X и Y одинаковы, возникает ошибка времени компиляции.

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

Если S является окончательным классом (§8.1.1), то S должен реализовать T, или возникает ошибка времени компиляции.


Следующий код компилирует:

interface Roamable{} 
class Phone {} 
class Tablet extends Phone implements Roamable { 
    Roamable var = (Roamable)new Phone(); // Compiles 
} 
+0

Код компилируется, но вопрос заключается в том, 'какой параметр позволит ссылочной переменной типа Roamable ссылаться на объект класса Phone'. Переменная может ссылаться только на объект во время выполнения, и это не сработает, поскольку это вызовет исключение ClassCastException. – Reboot

+0

@Reboot I (и, похоже, автор проблемы) считал это «во время компиляции». Вы совершенно правы, хотя он будет взрываться, если вы запустите. – Bohemian

+1

Это вопрос из учебной книги, и если это действительно так написано в книге, тогда ответ в книге неверен, и правильный ответ равен 4. Если это подразумевается как правильный ответ в книге, это подразумевает тогда вопрос плохо написан. В любом случае книга неверна. – Reboot

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