hey can you tell me how does the output comes in the following code?

huangapple go评论67阅读模式
英文:

hey can you tell me how does the output comes in the following code?

问题

我对这段代码的工作原理有点困惑你能帮忙吗我正在尝试深入理解它因此请随意提供任何关于这个主题的深入理解的链接输出结果是 A B B A

public class RuntimePolymorphism {
    public static void main(String[] args) {
        A a = new B();
        B b = new B();

        System.out.println(a.c + " " + a.getValue()
            + " " + b.getValue() + " " + b.getSuperValue());
    }
}

class A {
    char c = 'A';

    char getValue() {
        return c;
    }
}

class B extends A {
    char c = 'B';

    char getValue() {
        return c;
    }

    char getSuperValue() {
        return super.c;
    }
}
英文:

I am a bit confused about how this code works can you help. I am trying to understand it in deep. So please feel free to refer any links for depth understanding about the subject matter.The output is A B B A

    public class RuntimePolymorphism {
        public static void main(String[] args) {
            A a = new B();
            B b = new B();

            System.out.println(a.c + " " + a.getValue()
                + " " + b.getValue() + " " + b.getSuperValue());
        }
    }
      
    class A {
        char c = 'A';

        char getValue() {
            return c;
        }
    }
      
    class B extends A {
        char c = 'B';

        char getValue() {
            return c;
        }

        char getSuperValue() {
            return super.c;
        }
    }

答案1

得分: 1

实际上,这是一个有趣的问题 hey can you tell me how does the output comes in the following code? 通过代码,乍一看,我会说,它应该输出 A A B A,但它实际上输出了 A B B A

然后,我发现了一个可能的错别字(或者这是有意的,不清楚):

A a = new B();
B b = new B();

这里有两个 B,但我们在实例化 a 变量时进行了类型转换。即使我们将字段 c 设置为 public,它仍然产生相同的结果。

但是,另一方面,如果我们将代码更新为这样:

A a = new A();
B b = new B();

一切都会如预期:A A B A


有趣的发现:如果我们从 B 类中移除重载的 getValue() 方法,输出将会是 A A A A...


最终结论: 我们可以继承一个非私有字段(这样我们可以从派生类访问它),但我们不能像方法那样“重载”它。

因此,在Java中,多态性仅适用于方法,而不适用于字段。

英文:

Actually, it's an interesting question ;), by the code, from the fist sight, I would say, it should output A A B A, yet it producing A B B A.

Then, I found a possible typo (or it was intentional, don't know):

A a = new B();
B b = new B();

we have two B's here, but we are also doing a type casting at the moment of instantiation of a variable. Even if we make c field as public it still produces the same result.

But, on the other hand, if we'll update to code like this:

A a = new A();
B b = new B();

everything will be as expected: A A B A.


Interesting finding: if we remove overloaded getValue() from the B class, the output will be<br> A A A A...


Final conclusion: we can inherit a non-private field (that's we can access it from derived class), but we can't "overload" it the way we do with methods.

Thus, in Java, polymorphism is only working with methods and not with the fields.

答案2

得分: 0

实例变量 C 来自 A,在 B 中被简单隐藏<br>
– A.C 是 'A',因为它在类 A 中设置<br>
– A.getValue() 返回 'B',因为该对象的类型是 B

英文:

The instance variable C from A is simply hidden in B<br>
– A.C is ‘A’ because it's set in the class A<br>
– A.getValue() returns ‘B’ because the object is of type B

答案3

得分: 0

因此,我认为我们首先应该了解隐藏多态性之间的区别。

当你用与超类变量相同的变量名声明一个子类时,子类变量只是隐藏了超类变量。

对于运行时多态性,子类方法需要覆盖超类方法。当子类中的方法与其超类中的方法具有相同的签名(名称和参数)和相同的返回类型时,子类中的方法会覆盖超类中的方法。

另一个重要的观点是,多态性(在这种情况下是运行时多态性)作用于在运行时评估的方法。但变量的值的初始化发生在编译时。

  1. 因此,当执行 A a = new B(); 时,a 的实例变量 c 具有值 'A'。因此,即使引用 a 指向 B 对象,它所引用的实例变量仍将是 A 的。

因此,当我们运行 a.c 时,输出将为 A

  1. 但由于子类中覆盖了方法 getValue(),a 将调用覆盖的方法(因为它指向子类 B 对象)。

因此,当我们运行 a.getValue() 时,输出将为 B

因此,当执行 B b = new B(); 时,b 的实例变量 c 具有值 'B'。这隐藏了超类的变量 c。如果我们想引用直接超类的实例变量,则通过 super.<variable_name> 进行访问。因此,即使引用 a 指向 B 对象,它所引用的实例变量仍将是 A 的。

  1. 引用 b 指向一个类型为 B 的对象,因此它将调用 BgetValue() 方法。

因此,当我们运行 b.getValue() 时,输出将为 B

  1. 正如上面所讨论的,我们通过 super.<variable_name> 访问直接超类的实例变量。

因此,当我们运行 b.getSuperValue() 时,输出将为 A

英文:

So I think we should first understand the difference between Hiding and Polymorphism.

When you declare a subclass with a variable name the same as the superclass variable, then the subclass variable just hides the superclass variable.

For Runtime Polymorphism, a subclass method would need to override a superclass method. When a method in a subclass has the signature ( name and parameters ) and same return type as a method in its superclass, then the method in the subclass overrides the method in the superclass.

Another important point is that Polymorphismm ( Runtime in this case ) acts on methods that are evaluated at run time. But the initialization of values to the variables happens at compile time.

  1. So, when A a = new B(); is executed, a's instance variable c has the value &#39;A&#39;. So even if the reference a is pointing to a B object, the instance variables it refers to would be that of A.

Hence the output when we run a.c would be A.

  1. But since the method getValue() is overriden in the subclass, a would call the overriden method ( because it is pointing to the subclass B object ).

Hence the output when we run a.getValue() would be B

So, when B b = new B(); is executed, b's instance variable c has the value &#39;B&#39;. And this hides the variable c of the superclass. And if we want to refer to the immediate superclass's instance variables then we access it via super.&lt;variable_name&gt; So even if the reference a is pointing to a B object, the instance variables it refers to would be that of A.

  1. The reference b is pointing to an object of type B and hence it would call B's getValue() method.

Hence the output when we run b.getValue() would be B.

  1. As discussed above, we access the immediate superclass's instance variables via super.&lt;variable_name&gt;

Hence the output when we run b.getSuperValue() would be A

huangapple
  • 本文由 发表于 2020年9月3日 15:58:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/63719245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定