[英]Why can this object access methods of it's parent class?
This question is taken from an AP Computer Science practice test. 这个问题取自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");
}
}
Suppose the following declaration appears in a class other than Bird or Dove: 假设以下声明出现在Bird或Dove以外的类中:
Bird pigeon = new Dove();
What is printed as a result of the call pigeon.act()
? 调用
pigeon.act()
会打印什么?
I thought the answer would be "fly chirp", but the textbook says that the answer is "fly chirp coo waddle". 我认为答案是“飞唧唧”,但教科书说答案是“飞唧唧唧唧”。 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.
我的印象是,如果用户想要访问Dove中的方法,那么'鸽子'将被投射到Dove。
Would Bird pigeon = new Bird();
Bird pigeon = new Bird();
give the same output? 给出相同的输出? How about
Dove pigeon = new Dove();
Dove pigeon = new Dove();
? ?
Long story short, when you access act
method of pigeon
, its override from Dove
is called. 长话短说,当你访问
pigeon
act
方法时,它被称为Dove
。
I thought that 'pigeon' could only access methods available in Bird?
我认为'鸽子'只能使用伯德的方法吗?
That is certainly true, at least, for situations when no casting is applied. 至少,对于没有应用铸造的情况,这当然是正确的。 However, method
act
is available on the class Bird
, the statically known type of pigeon
, so the call compiles fine. 但是,方法
act
可用于Bird
类,这是一种静态类型的pigeon
,因此呼叫编译良好。
However, accessing methods is only about being able to call them. 但是, 访问方法只是能够调用它们。 What methods do when you call them is decided at runtime based on the dynamic type of
pigeon
. 调用它们时,用什么方法根据
pigeon
的动态类型在运行时决定。 This is where method overriding comes into play, because Dove
overrides Bird
's methods, but in addition it also calls Bird
's methods. 这是方法重写发挥作用的地方,因为
Dove
重写了Bird
的方法,但此外它还调用了Bird
的方法。 That is why the code hits all four printouts. 这就是代码击中所有四个打印输出的原因。
Would
Bird pigeon = new Bird();
Bird pigeon = new Bird();
give the same output?给出相同的输出?
No, the output would be different, because in this case both dynamic and static types of pigeon
would be the same, ie Bird
, so only Bird
's implementations would be invoked. 不,输出会有所不同,因为在这种情况下,动态和静态类型的
pigeon
都是相同的,即Bird
,因此只会调用Bird
的实现。
What you experience here is polymorphism in action. 你在这里遇到的是多态性 。 And instead of answering your various questions directly;
而不是直接回答你的各种问题; I will simply explain the case you are observing.
我将简单解释你正在观察的案例。
You call act()
on an instance of Dove; 你在Dove的一个实例上调用
act()
; that causes a call to super; 这导致超级电话; printing "fly".
印刷“飞”。
That super method then calls makeNoise()
... on "itself". 那个超级方法然后调用
makeNoise()
... on“ makeNoise()
”。 But as said: "itself" is a Dove object; 但正如所说:“本身”是一个鸽子对象; thus you get the Dove noise!
因此你得到了鸽子的声音! "coo"!
“COO”!
Then the Dove implementation ends; 然后Dove实现结束; and prints "waddle".
并打印“蹒跚”。
The essence is: the exact version of a method that is invoked is determined at runtime and it only depends on the exact type of the object the method is invoked on. 本质是:调用的方法的确切版本是在运行时确定的, 它只取决于调用该方法的对象的确切类型。
The above gives you all the information you need to answer your other questions yourself. 以上内容为您提供了自己回答其他问题所需的所有信息。 In that sense: don't request answers;
在这个意义上:不要求答案; ask for explanations;
请求解释; and use those to solve the puzzle yourself!
并用自己来解决这个难题!
Dove
does override the methods act
and makeNoise
of class Bird
. Dove
没有覆盖的方法act
和makeNoise
类的Bird
。 Overriding means changing the behavior of a method visible to the sub-class, (in your case Dove
). Dove
)。 Methods are visible to a sub-class if they have a public
or protected
access modifier or if they have a package private
access modifier and the sub-class belongs to the same package as the super-class does. public
或protected
访问修饰符,或者如果它们具有package private
访问修饰符并且子类属于与超类相同的包,则子类可见方法。 pigeon
is an instance of Dove
. pigeon
是一个实例Dove
。 pigeon.act()
results in calling Dove.act
. pigeon.act()
导致调用Dove.act
。 Dove.act
calls super.act
which is Bird.act
. Dove.act
调用super.act
,它是Bird.act
。 Bird.act
prints fly
and calls makeNoise
on pigeon
resulting in calling Dove.makeNoise
. Bird.act
打印fly
并在pigeon
上调用makeNoise
,导致调用Dove.makeNoise
。 Dove.makeNoise
calls super.makeNoise
which is Bird.makeNoise
. Dove.makeNoise
调用了super.makeNoise
,它是Bird.makeNoise
。 Bird.makeNoise
print chirp
. Bird.makeNoise
打印chirp
。 Dove.makeNoise
prints coo
after calling super.makeNoice
Dove.makeNoise
打印coo
打完电话后super.makeNoice
From your question "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." 从你的问题“我认为'鸽子'只能访问Bird中可用的方法?我的印象是,如果用户想要访问Dove中的方法,'鸽子'就必须投向Dove。” This is actually true .
这确实是事实 。
Lets try to find the mssing link in the understanding. 让我们试着在理解中找到mssing链接。
When we have code like Bird pigeon = new Dove();
当我们有代码像
Bird pigeon = new Dove();
where Dove
extends Bird
we have actual object of Dove
and reference type is of Bird
. 在
Dove
延伸Bird
我们有Dove
实际对象,参考类型是Bird
。 As the object is of Dove
so it has the methods, both inherited from super class as well as the ones which are added . 因为对象是
Dove
所以它有方法,都是从超类继承而来的,也是添加的方法 。
Another important point is all the overriden
methods have only one instance. 另一个重点是所有
overriden
方法只有一个实例。 Its Overriden meaning the behavior of the same method has been modified, its not an additional separate method. 它的Overriden意味着同一方法的行为已被修改,它不是一个额外的单独方法。 There is only one copy of inherited method not both.
只有一个继承方法的副本,而不是两个。 Its the overloaded methods which are separate, just the names are same but signature is different.
它的重载方法是分开的,只是名称相同但签名不同。 This is the reason you get the behaviour of Dove when you invoke any overriden method.
这是您在调用任何override方法时获得Dove行为的原因。
This one is simple super
, using it a sub class can access the accessible (visible) entities (instance properties and methods) of its super class. 这个是简单的
super
,使用它,子类可以访问其超类的可访问(可见)实体(实例属性和方法)。 If a sub class uses super
keyword to invoke a method then its the method of the parent class which gets invoked. 如果子类使用
super
关键字来调用方法,那么它将调用父类的方法。 But again this can be considered that the author of the sub class did it intentionally. 但同样可以认为子类的作者故意这样做了。 Once the class is written and Objects of such class is created then on the object using
.
一旦编写了类,就创建了这类的对象,然后在对象上使用
.
(dot operator) users can only invoke whats there in the object. (点运算符)用户只能调用对象中的内容。 If any method has used
super
keyword its part of the behavior of the object. 如果任何方法使用了
super
关键字,那么它就是对象行为的一部分。 Users of the Sub class object can not invoke behavior of the parent class method if its overridden in sub class. 如果子类对象在子类中被重写,则它们不能调用父类方法的行为。
Lastly yes if you wish to invoke any additional method of Dove
(Sub class ) using a reference of Bird
(Super class) then you need to cast it to Dove
. 最后是的,如果你想使用
Bird
(Super class)的引用来调用Dove
(Sub类)的任何其他方法,那么你需要将它转换为Dove
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.