简体   繁体   English

与这个简单的多态示例混淆

[英]Confused with this simple example of polymorphism

Please have a look at this code : 请看下面的代码:

class Foo {
    public int a;
    public Foo() {
        a = 3;
    }
    public void addFive() {
        a += 5;
    }
    public int getA() {
        System.out.println("we are here in base class!");
        return  a;
    }
}

public class Polymorphism extends Foo{
    public int a;
    public Poylmorphism() {
        a = 5;
    }
    public void addFive() {
        System.out.println("we are here !" + a);
        a += 5;
    }
    public int getA() {
        System.out.println("we are here in sub class!");
        return  a;
    }

    public static void main(String [] main) {
        Foo f = new Polymorphism();
        f.addFive();
        System.out.println(f.getA());
        System.out.println(f.a);
    }
}

Here we assign reference of object of class Polymorphism to variable of type Foo , classic polmorphism. 在这里,我们将类“ Polymorphism的对象的引用分配给类型为Foo变量(经典多态)。 Now we call method addFive which has been overridden in class Polymorphism . 现在我们调用方法addFive ,该方法已在类Polymorphism被覆盖。 Then we print the variable value from a getter method which also has been overridden in class Polymorphism. 然后,我们从getter方法打印变量值,该方法在Polymorphism类中也已被覆盖。 So we get answer as 10. But when public variable a is SOP'ed we get answer 3!! 因此我们得到的答案为10。但是当公共变量a为SOP时,我们的答案为3!

How did this happen? 这怎么发生的? Even though reference variable type was Foo but it was referring to object of Polymorphism class. 尽管引用变量类型是Foo,但是它引用的是Polymorphism类的对象。 So why did accessing fa not result into value of a in the class Polymorphism getting printed? 那么,为什么在打印Polymorphism类中访问fa不会导致a的值? Please help 请帮忙

You're hiding the a of Polymorphism - you should actually get a compiler warning for that. 你躲在aPolymorphism -你真正应该得到一个编译器的警告。 Therefore those are two distinct a fields. 因此,这是两个不同a领域。 In contrast to methods fields cannot be virtual. 与方法相反,字段不能是虚拟的。 Good practice is not to have public fields at all, but only methods for mutating private state (encapsulation). 优良作法是根本不拥有公共字段,而只有用于改变私有状态(封装)的方法。

If you want to make it virtual, you need to make it as a property with accessor methods (eg what you have: getA ). 如果要使其虚拟化,则需要使用访问器方法(例如,拥有的内容: getA )将其设置为属性。

This is due to the fact that you can't override class varibles. 这是因为您不能覆盖类变量。 When accessing a class variable, type of the reference, rather than the type of the object, is what decides what you will get. 当访问一个类变量时,引用的类型而不是对象的类型决定了您将获得什么。

If you remove the redeclaration of a in the subclass, then I assume that behaviour will be more as expected. 如果您在子类中删除了a的重新声明,那么我认为该行为将更加符合预期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM