给出以下代码:
//Super class
class A {
void m1() {
System.out.println("A");
}
}
//Extending the super class
class B extends A {
void m1() {
System.out.println("B");
}
}
// Class with the main method
public class C extends B {
void m1() {
System.out.println("C");
}
}
//in some main method
B b1 = new B(); //creating B object
System.out.println(b1 instanceof A); //gives true
B b = (B) new A();
b.m1();
instanceof
运算符为true,因此B
是类A
的对象。A
B
ClassCastException
时,B
提出A
,numOfDocuments
是0
的子类型?答案 0 :(得分:7)
new A();
根本不是B
。
就像你说“每只动物都是猫,没有例外”一样。这不是真的。
但是,将B
投射到A
是正确的(因为每只猫都是动物,没有例外):
A a = (A) new B();
答案 1 :(得分:1)
A a = new B(); // is fine as B inherits A
B b = new A(); // is NOT fine as A does not inherit any thing from B
答案 2 :(得分:0)
B是A的一个实例,它是正确的。但是A不是B的实例。这就是你得到例外的原因。
答案 3 :(得分:0)
B b = (B) new A();
是错误的陈述,因为A
不会继承B
;而B
继承A
答案 4 :(得分:0)
由于一些原因,允许这样的铸造是不安全的。
1)假设您添加了B
其他A
无法使用的字段
class A {
void m1() {
System.out.println("A");
}
}
class B extends A {
void m1() {
System.out.println("B");
}
private int x;
public void setX(int x) {
this.x = x;
}
}
现在让我们假设这个转换会起作用
B b = (B) new A();
因此b
将保留A
的实例。但稍后我们可以尝试从setX
引用
B
b.setX(1);
应该没问题,因为没有强制转换异常,因此来自B
引用的对象应该能够支持此调用。
您怎么看?JVM应该如何应对下一行?这样的代码应该被允许吗?
不,基地A
不知道应该为setX
执行哪些代码,即使它知道它,它也没有int x
字段存储其数据。因此,为了防止这种情况,JVM会抛出ClassCastException。
2)您可以这样说:" 好的,但我的B
没有更改界面,它不会向A
<添加任何新内容/ EM>&#34 ;.你是对的,但在这种情况下允许转换也很危险,因为从B
调用方法时,你应该能够期望它们的行为方式与B
类或其子类中描述的方式相同。
让我们说我们正在建立赛车游戏,我们有课程
class Car{
int getMaxSpeed(){
200;
}
}
class LimitedSpeedCar extends Car{
int getMaxSpeed(){
return 30;
}
}
现在,您只想为速度有限的汽车创建赛道。因此,您正在创建LimitedSpeedCar[]
数组,以仅存储速度有限的汽车。但是猜猜是什么,因为
B b = (B) new A();
工作正常意味着
LimitedSpeedCar lsc = (LimitedSpeedCar) new Car();
也会有效,所以我们可以加入我们的赛车,没有限制,这不是我们想要的。
答案 5 :(得分:0)
B
是A
的子类,您无法将A
投射到B
。实际上,新A
对象的具体类可能是B
之外的另一个类(比如扩展C
的类A
)。因此,您无法确认A
是B
的实例。
答案 6 :(得分:0)
类型B的对象可以转换为A类变量,但不能转换为其他方式。 B扩展了A,因此它可能具有更多功能。这可能是回顾和阅读多态性的好时机。
答案 7 :(得分:0)
你无法向下施放物体。你可以创建一个
A a1 = new B()
。
但你无法创建
B b1 = new A()
但你不能确定每只狗都是德国谢泼德。因此不支持创建新的德国Shepard型狗。 阅读This