type变量
A可以
A像在case类中那样存储对类型或其子类型的对象的引用
B。
因此,可能会有类似以下的代码:
A a = new B();
变量
a是类型的,
A因此它只能访问该类的API,而不能访问在类B中添加的方法,即它所指向的对象。但是有时我们希望能够访问那些方法,因此应该可以以某种方式将引用存储
a在更精确类型的某个变量中(在此
B),通过该变量我们可以访问B类中的其他方法。
但是我们如何去做?
让我们尝试通过以下方式实现它:
B b = a;//WRONG!!! "Type mismatch" error
这样的代码会给出编译时
Type mismatch错误。碰巧使我们免于这种情况:
class B1 extends A
class B2 extends A
而且我们有
A a = new B1();。
现在让我们尝试分配
B1 b = a;。请记住,
编译器不知道变量中实际包含的内容,
a因此它需要生成对所有可能的值都安全的代码。如果编译器不会抱怨,
B1 b = a;也应该允许编译
B2 b= a;。因此,为了安全起见,我们不允许这样做。
所以,我们应该做些什么来分配基准从
a到
B1?我们需要 明确
告诉编译器,这里我们意识到潜在的类型不匹配问题,但是我们确保
a可以安全地将持有的引用分配给type变量
B。我们通过 将 值从
a类型 转换
为类型
B来实现
(B)a。
B b = (B)a;
但是让我们回到您的问题的例子
B b1 = (B) new A();A a1 = (B) new A();
new运算符返回与创建对象相同类型的
new A()引用,因此返回该类型的引用,
A因此
B b1 = (B) new A();
可以看作是
A tmp = new A();B b1 = (B) tmp;
这里的问题是 您不能在其派生类型的变量中存储对超类对象的引用 。
为什么存在这种限制?可以说派生类添加了一些超类型不喜欢的新方法
class A { // some pre}class B extends A { private int i; public void setI(int i){ this.i=i; }}
如果允许的话
B b = (B)new A();
您以后可能会调用
b.setI(42);。但这是正确的吗?否,因为类A的实例没有方法
setI或该方法使用的 字段
i。
所以要防止这种情况
(B)new A();在 运行时 抛出
java.lang.ClassCastException。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)