2014-02-16 99 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类的实例时,你可以键入cast到Tablet(类似于你可以投ObjectString)。而且由于Tablet实现了Roamable,所以您可以很好地使用Roamable引用来引用它。 Problem will occur at runtime作为Object确实是Phone类型。

这只是允许成功编译的联动模式之一(在当前上下文中)。但是,随着波希米亚已经在他的回答一般

提到如果我们是一个类型转换编译时间基准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被转换为RoamablePhone不是终点,所以它认为对象虽然被称为Phone可能是Phone的子类确实实施Roamable,所以没有编译时错误或警告发出。

根据JLS chapter 5

5.5.1。参考类型转换

鉴于编译时引用类型S(源极)和一个编译时引用类型T(目标),流延转换选自S存在如果由于没有发生编译时错误到T以下规则。 如果T是接口类型:

如果S不是最终类(第8.1.1.1节),那么如果存在T的超类型X和S的超类型Y,使得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