简体   繁体   English

为什么这个对象可以访问它的父类的方法?

[英]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! 并用自己来解决这个难题!

  • the class Dove does override the methods act and makeNoise of class Bird . Dove没有覆盖的方法actmakeNoise类的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. 如果子类具有publicprotected访问修饰符,或者如果它们具有package private访问修饰符并且子类属于与超类相同的包,则子类可见方法。
  • pigeon is an instance of Dove . pigeon是一个实例Dove
  • calling 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链接。

  1. 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所以它有方法,都是从超类继承而来的,也是添加的方法

  2. 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行为的原因。

  3. 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. 如果子类对象在子类中被重写,则它们不能调用父类方法的行为。

  4. 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.

相关问题 为什么引用子类对象的父类类型引用变量无法访问子类的方法 - Why parent class type reference variable having reference to child class object can't access child class's Methods 无法访问对象的方法 - Can't access an object's methods 为什么我可以访问父类中的子方法? - Why am I able to access child methods in the parent class? 访问父类的方法和变量 - Access parent class methods and variables 为什么对父 class 构造函数的调用不调用在子 class 中覆盖的父方法? - Why does the call to a parent class constructor not call the parent's methods that are overriden in the child class? 为什么我不能从另一个 class 访问对象的属性? (即使 Object 被传递给试图访问属性的 class) - Why can't I access the Object's properties from another class? (even when the Object was passed to the class that is trying to access the properties) 无法从Java中的ArrayList访问对象的方法 - Can't access an object's methods from an ArrayList in Java 为什么匿名类不能访问私有方法和变量? - Why anonymous class can't access private methods and variables? 为什么我的班级成员无法访问我的getter方法? - Why can't my class members access my getter methods? 为什么“THIS”关键字将子对象表示为父类的方法? - Why "THIS" keyword denotes Child object into Parent class's method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM