(之前的问题是here。我没有得到理想的答案。)
一本书的引用:
如果要调用由对象的子类定义的方法,该怎么办? 那是由超类的变量引用的?假设是SoftBall类 有一个名为riseBall的方法,它不是由Ball类定义的。你怎么 从Ball变量调用它?一种方法是创建子变量 class然后使用赋值语句来转换对象:
Ball b = new SoftBall();
SoftBall s = (SoftBall)b;
// cast the Ball to a
// SoftBall
s.riseBall();
在上面的代码片段中,它显示了一个新的垒球对象被创建并被指定为对变量 b 的引用,这是完全合法的,因为类垒球是 Ball 类的子类。然而,引用声明(间接)您必须先将变量强制转换为 Softball ,然后才能使用该变量从 Softball 类调用方法。这是为什么?为什么我不能直接使用 Ball 类型的变量b(其中包含对Softball对象的引用)来调用所需的方法?变量 b 已经有了对象。
(注意:我已经阅读了this帖子。)
答案 0 :(得分:4)
Java是一种静态类型语言。
这意味着编译器会检查变量的类型是否具有您尝试调用的方法。
变量b
的类型为Ball
。 Ball
没有riseBall
方法。
这意味着您的代码会崩溃,除非运行时b
恰好包含Softball
(编译器无法保证)。您可能知道它确实如此,但您也必须说服编译器(即为您的变量提供必要的类型)。
答案 1 :(得分:1)
Ball b = new SoftBall();
这只是意味着变量b是Ball类型,但是如果在Ball类中出现的方法在扩展类SoftBall中被覆盖,那么使用变量' b',我们将调用方法定义class' SoftBall'而不是' Ball'。 现在,虽然变量b指的是类' SoftBall'的实现,但它仍然属于类' Ball'和Ball类没有任何方法' riseBall'
希望这是有道理的。
答案 2 :(得分:0)
因为公开的方法取决于声明的变量类型。
Ball b = new SoftBall();
b
实际上是SoftBall
,但您正在“隐藏”它,因为您将其声明为Ball
类型。由于Ball
类型没有riseBall
方法,因此您无法通过询问b
来访问它。
答案 3 :(得分:0)
我们知道java
是statically typed language
。
这是statically-typed languages的一项功能,其中变量会提前分配一个类型,并在compile-time
处检查以查看类型是否匹配。
如果此代码是在dynamically-typed language上执行的,那么在运行时检查类型,可以允许以下类似的内容:
Ball b = new SoftBall();
if (b instanceof SoftBall){
b.riseBall();
}
保证 b.riseBall()
仅在实例为SoftBall
时执行,因此对riseBall
的调用始终有效。
但是,Java是一种静态类型的语言,所以这种类型的代码是 不允许。