我有2个软件包:控制器和联合身份验证。控制器仅包含具有main方法的控制器类,但联合身份验证包含2个类,Shuttle(父类)和MiniShuttle(子类)。向上转换的工作原理很吸引人,但是当我尝试向下转换时,会收到ClassCastException。
这是我尝试的代码:
Shuttle.java
package federation;
public class Shuttle {
protected int passengers;
}
MiniShuttle.java
package federation;
public class MiniShuttle extends Shuttle {
}
Controller.java
package controller;
import federation.MiniShuttle;
import federation.Shuttle;
public class Controller {
public static void main(String[] args) {
Shuttle shuttle = new Shuttle();
MiniShuttle mshuttle = (MiniShuttle)shuttle;
if(mshuttle instanceof Shuttle)
{
System.out.println("ok");
}else
{
System.out.println("not ok");
}
}
}
答案 0 :(得分:3)
因为您已实例化Shuttle
。声明new Shuttle()
表示实例化类型为Shuttle
的对象,对该对象的引用为Shuttle
(来自Shuttle shuttle = ...
)。
如果要使其正常工作,请使用Shuttle shuttle = new MiniShuttle()
。这样,您实际上是在说“我正在实例化一个MiniShuttle
类型的对象,并将对该对象的引用上载为Shuttle
类型的对象。”
答案 1 :(得分:2)
正如您所说,您正在下铸造,这意味着要从父辈投射到孩子-因为shuttle
的类型为Shuttle
并且不是MiniShuttle
。
您可以用另一种方法来做
MiniShuttle miniShuttle = new MiniShuttle();
Shuttle shuttle = (Shuttle) miniShuttle;
这样,您就可以进行广播了,这非常好,因为每个MiniShuttle
也是Shuttle
。
答案 2 :(得分:0)
OOPS中的合同是由超级类而不是子类定义的。 基本上,扩展合同被定义为“是”关系,其中子类是父类的对象,反之亦然
以这种方式阅读,MiniShuttle是Shuttle,但Shuttle不是MiniShuttle
答案 3 :(得分:0)
您在main方法的第1行中将“ shuttle”实例化为通用Shuttle对象,但随后尝试将其强制转换为MiniShuttle。您不能这样做,因为Shuttle不一定是MiniShuttle,而是其他东西。这是另一个示例,希望可以更清楚地说明为什么这将是一个错误的假设,而更具体的示例将说明为什么这是一个错误的假设。
form = u'{:<{width}}\t{:<3}({})'
for line in a:
line = line[:12]
adjust = len(line) - malayalam_width(line)
print form.format(line, 1, 2, width=12 + adjust)
FerengiShuttle是一种穿梭,而mshuttle也是一种穿梭,但是ssQuark并不是MiniShuttle,也从未打算这样做。如果您有通用的Shuttle对象,则无法进行向下转换所需的必要假设。