有人可以解释一下这种多态性的输出吗?

时间:2013-08-23 17:18:53

标签: java polymorphism ocpjp

下面是代码:

class A{
    int data=10;
    void show1(){
        System.out.println("In A="+data);
    }
}

class B extends A{
    int data=20;
    void show2(){
        System.out.println("In B="+data);
    }



}


public class Overriding4 {
    public static void main(String args[]){
        B b=new B();
        System.out.println("Data1="+b.data);
        System.out.println("Data2="+b.data);
        b.show1();
        b.show2();
    }
}

继续输出:

Data1=20
Data2=20
In A=10
In B=20

Data1 = 20的输出应为10,而不是20 ......但我想我在这里遗漏了一些东西。请帮帮我这个

好的,感谢您的帮助,但又有一个新疑点: 如果我将main方法更改为:

会发生什么
 public static void main(String args[]){
            A a=new B();
            System.out.println("Data1="+a.data);
            System.out.println("Data2="+a.data);
            a.show1();
            a.show2();
        }

你去。

7 个答案:

答案 0 :(得分:1)

类字段不会被继承。请注意,您在int dataA这两个类中都有相同的B字段。这称为Hiding

答案 1 :(得分:1)

为了“感受”多态性的力量,我们需要稍微改变你的代码:

class A {

    int data=10;
    void show(){
        System.out.println("In A="+data);
    }
}

class B extends A {

    int data=20;

    @Override
    void show(){
        System.out.println("In B="+data);
    }

    public static void main(String args[]){
        A a = new A();
        A b = new B();
        a.show();
        b.show();
    }
}

现在,您可以看到ab都被声明为A类型 - 但分配是产生差异的原因。此外,我们可以创建一个A类型的数组,并使用两种类型的对象(A以及B)来容纳它:

A[] arr = new A[3];

//让我们添加一些内容;

arr[0] = new A(); 
arr[1] = new B();
arr[2] = new A();

现在很容易看出多面体是多么美丽的作品

for (int i=0; i<arr.length; i++){
   arr[i].show();
}

最后一个循环将打印:

In A 10
In B 20
In A 10

我们所知道的是数组包含A子类型的对象 - 我们可以指望每个对象调用“正确的”show()方法。那是多态的!

答案 2 :(得分:1)

Within a class, a field that has the same name as a field in the superclass hides
the superclass's field, even if their types are different. 

这可以在Hiding fields

中找到

因此,它打印20。

答案 3 :(得分:0)

由于您已在B类中覆盖了数据变量,因此它将打印最新值。由于您在B类中将“数据”重新评估为20,这就是它将显示的内容。

答案 4 :(得分:0)

B的对象有两个字段,都名为data,但正如Luiggi暗示的那样,其中一个字段是隐藏的。如果你想要取回它,请使用演员:

public class Overriding4 {
    public static void main(String args[]){
        B b=new B();
        System.out.println("Data1="+((A)b).data);  // like this  
        System.out.println("Data2="+b.data);
        b.show1();
        b.show2();
    }
}

产生

Data1=10
Data2=20
In A=10
In B=20

P.S。您可以在作业的任一侧使用演员表:

public class Overriding4 {
    public static void main(String args[]){
        B b=new B();
        ((A)b).data *= 10;
        System.out.println("Data1="+((A)b).data);  
        System.out.println("Data2="+b.data);
        b.show1();
        b.show2();
    }
}

Data1=100
Data2=20
In A=100
In B=20

PPS。我发布了这个以向您展示语言是如何工作的,但总的来说,是一个好主意,在其他类可以直接读写的类中使用公共字段。见Why use getters and setters?

答案 5 :(得分:0)

除非您输错,否则以下两行基本相同:

System.out.println("Data1="+b.data);
System.out.println("Data2="+b.data);

像这样可视化对象可能会有所帮助:

A {
  [A.data = 10];  <-- this is overridden and cannot be accessed directly
  show1() => 10;
  B {
    B.data => 20;
    show2() => 20;
  }
}

答案 6 :(得分:0)

你实际上没有覆盖方法......

`的System.out.println( “数据1 =” + b.data);

的System.out.println( “数据2 =” + b.data);`

对于这两行,“data”值将从B类的数据变量中获取。 现在,类B已经扩展了类A,这意味着类A的所有成员将在类B中继承。所以变量i(类A)将被继承,而在类B中我们有自己的局部变量i .....类A的.show1()方法也将在类B中继承。 因此,通过使用B类的引用变量(b),我们可以访问show1()方法以及show2()方法。