为什么此对象可以访问其父对象 class 的方法?
Why can this object access methods of it's parent class?
此题取自 AP 计算机科学实践测试。
public class Bird
{
public void act()
{
System.out.print("fly");
makeNoise();
}
public void makeNoise()
{
System.out.print("chirp");
}
}
public class Dove extends Bird
{
public void act()
{
super.act();
System.out.print("waddle");
}
public void makeNoise()
{
super.makeNoise();
System.out.print("coo");
}
}
假设以下声明出现在除 Bird 或 Dove 之外的 class 中:
Bird pigeon = new Dove();
调用 pigeon.act()
的结果打印了什么?
我以为答案会是"fly chirp",但教科书上说答案是"fly chirp coo waddle"。我以为 'pigeon' 只能访问 Bird 中可用的方法?我的印象是,如果用户想要访问 Dove 中的方法,则必须将 'pigeon' 强制转换为 Dove。
Bird pigeon = new Bird();
会给出相同的输出吗? Dove pigeon = new Dove();
怎么样?
长话短说,当您访问 pigeon
的 act
方法时,会调用 Dove
的覆盖方法。
I thought that 'pigeon' could only access methods available in Bird?
这当然是正确的,至少在没有应用转换的情况下是这样。但是,方法 act
在 class Bird
上可用,pigeon
的静态已知类型,因此调用编译正常。
然而,访问方法只是为了能够调用它们。当你调用它们时方法做什么是在运行时根据 pigeon
的 dynamic 类型决定的。这就是方法覆盖发挥作用的地方,因为 Dove
覆盖了 Bird
的方法,但此外它还调用了 Bird
的方法。这就是代码命中所有四个打印输出的原因。
Would Bird pigeon = new Bird();
give the same output?
不,输出会不同,因为在这种情况下 pigeon
的动态和静态类型是相同的,即 Bird
,所以只有 Bird
的实现将被调用。
您在这里体验到的是多态性的实际应用。而不是直接回答你的各种问题;我就简单说明一下你观察到的情况。
您在 Dove 实例上调用 act()
;这会导致调用 super;打印 "fly".
该超级方法随后调用 makeNoise()
... "itself"。但如前所述: "itself" 是一个 Dove 对象;因此你得到了鸽子的噪音! "coo"!
那么Dove实现结束;并打印 "waddle".
本质是:被调用的方法的确切版本在运行时[=30]确定=] 并且它 仅 取决于调用该方法的对象的确切类型。
以上内容为您提供了 所有 您需要自己回答其他问题的信息。从这个意义上说:不要要求答案;要求解释;并用它们自己解决难题!
- class
Dove
覆盖 class [=13] 的 act
和 makeNoise
方法=].覆盖意味着将方法 visible 的行为更改为子 class(在您的情况下为 Dove
)。如果方法具有 public
或 protected
访问修饰符,或者如果它们具有 package private
访问修饰符且子 class 方法对子 class 可见与 super-class 属于同一个包。
pigeon
是 Dove
. 的实例
- 调用
pigeon.act()
结果调用 Dove.act
.
Dove.act
调用 super.act
即 Bird.act
.
Bird.act
打印 fly
并在 pigeon
上调用 makeNoise
导致调用 Dove.makeNoise
.
Dove.makeNoise
调用 super.makeNoise
即 Bird.makeNoise
.
Bird.makeNoise
打印 chirp
.
Dove.makeNoise
在调用 super.makeNoice
后打印 coo
根据你的问题"I thought that 'pigeon' could only access methods available in Bird? I was under the impression that, if the user wanted to access methods in Dove, 'pigeon' would have to be cast to Dove."这实际上是正确。
让我们尝试在理解中找到 mssing link。
当我们有像 Bird pigeon = new Dove();
这样的代码时,其中 Dove
扩展 Bird
我们有 Dove
的实际对象并且引用类型是 Bird
.由于对象是 Dove
的,因此它具有方法,继承 来自 super class 以及 added。
另外一个重点是所有的overriden
方法只有一个实例。它的 Overriden 意味着同一方法的行为已被修改,它不是一个额外的单独方法。只有一个继承方法的副本,而不是两个。它的重载方法是分开的,只是名称相同但签名不同。这就是当您调用任何重写方法时获得 Dove 行为的原因。
这个很简单 super
,使用它一个 sub class 可以访问其 super [=55= 的可访问(可见)实体(实例属性和方法) ].如果子 class 使用 super
关键字来调用方法,那么它是被调用的父 class 的方法。不过这又可以认为sub class 的作者是故意的。一旦编写了 class 并创建了此类 class 的对象,然后在对象上使用 .
(点运算符)用户只能调用对象中的内容。如果任何方法使用了 super
关键字,则它是对象行为的一部分。 Sub class 对象的用户不能调用父 class 方法的行为,如果它在子 class.
中被覆盖
如果您希望使用 Bird
(超级 class 的引用调用 Dove
(子 class)的任何其他方法) 那么您需要将其转换为 Dove
。
此题取自 AP 计算机科学实践测试。
public class Bird
{
public void act()
{
System.out.print("fly");
makeNoise();
}
public void makeNoise()
{
System.out.print("chirp");
}
}
public class Dove extends Bird
{
public void act()
{
super.act();
System.out.print("waddle");
}
public void makeNoise()
{
super.makeNoise();
System.out.print("coo");
}
}
假设以下声明出现在除 Bird 或 Dove 之外的 class 中:
Bird pigeon = new Dove();
调用 pigeon.act()
的结果打印了什么?
我以为答案会是"fly chirp",但教科书上说答案是"fly chirp coo waddle"。我以为 'pigeon' 只能访问 Bird 中可用的方法?我的印象是,如果用户想要访问 Dove 中的方法,则必须将 'pigeon' 强制转换为 Dove。
Bird pigeon = new Bird();
会给出相同的输出吗? Dove pigeon = new Dove();
怎么样?
长话短说,当您访问 pigeon
的 act
方法时,会调用 Dove
的覆盖方法。
I thought that 'pigeon' could only access methods available in Bird?
这当然是正确的,至少在没有应用转换的情况下是这样。但是,方法 act
在 class Bird
上可用,pigeon
的静态已知类型,因此调用编译正常。
然而,访问方法只是为了能够调用它们。当你调用它们时方法做什么是在运行时根据 pigeon
的 dynamic 类型决定的。这就是方法覆盖发挥作用的地方,因为 Dove
覆盖了 Bird
的方法,但此外它还调用了 Bird
的方法。这就是代码命中所有四个打印输出的原因。
Would
Bird pigeon = new Bird();
give the same output?
不,输出会不同,因为在这种情况下 pigeon
的动态和静态类型是相同的,即 Bird
,所以只有 Bird
的实现将被调用。
您在这里体验到的是多态性的实际应用。而不是直接回答你的各种问题;我就简单说明一下你观察到的情况。
您在 Dove 实例上调用 act()
;这会导致调用 super;打印 "fly".
该超级方法随后调用 makeNoise()
... "itself"。但如前所述: "itself" 是一个 Dove 对象;因此你得到了鸽子的噪音! "coo"!
那么Dove实现结束;并打印 "waddle".
本质是:被调用的方法的确切版本在运行时[=30]确定=] 并且它 仅 取决于调用该方法的对象的确切类型。
以上内容为您提供了 所有 您需要自己回答其他问题的信息。从这个意义上说:不要要求答案;要求解释;并用它们自己解决难题!
- class
Dove
覆盖 class [=13] 的act
和makeNoise
方法=].覆盖意味着将方法 visible 的行为更改为子 class(在您的情况下为Dove
)。如果方法具有public
或protected
访问修饰符,或者如果它们具有package private
访问修饰符且子 class 方法对子 class 可见与 super-class 属于同一个包。 pigeon
是Dove
. 的实例
- 调用
pigeon.act()
结果调用Dove.act
. Dove.act
调用super.act
即Bird.act
.Bird.act
打印fly
并在pigeon
上调用makeNoise
导致调用Dove.makeNoise
.Dove.makeNoise
调用super.makeNoise
即Bird.makeNoise
.Bird.makeNoise
打印chirp
.Dove.makeNoise
在调用super.makeNoice
后打印
coo
根据你的问题"I thought that 'pigeon' could only access methods available in Bird? I was under the impression that, if the user wanted to access methods in Dove, 'pigeon' would have to be cast to Dove."这实际上是正确。
让我们尝试在理解中找到 mssing link。
当我们有像
Bird pigeon = new Dove();
这样的代码时,其中Dove
扩展Bird
我们有Dove
的实际对象并且引用类型是Bird
.由于对象是Dove
的,因此它具有方法,继承 来自 super class 以及 added。另外一个重点是所有的
overriden
方法只有一个实例。它的 Overriden 意味着同一方法的行为已被修改,它不是一个额外的单独方法。只有一个继承方法的副本,而不是两个。它的重载方法是分开的,只是名称相同但签名不同。这就是当您调用任何重写方法时获得 Dove 行为的原因。这个很简单
super
,使用它一个 sub class 可以访问其 super [=55= 的可访问(可见)实体(实例属性和方法) ].如果子 class 使用super
关键字来调用方法,那么它是被调用的父 class 的方法。不过这又可以认为sub class 的作者是故意的。一旦编写了 class 并创建了此类 class 的对象,然后在对象上使用.
(点运算符)用户只能调用对象中的内容。如果任何方法使用了super
关键字,则它是对象行为的一部分。 Sub class 对象的用户不能调用父 class 方法的行为,如果它在子 class. 中被覆盖
如果您希望使用
Bird
(超级 class 的引用调用Dove
(子 class)的任何其他方法) 那么您需要将其转换为Dove
。