3

我对多态概念感到困惑。请任何人都可以帮助我。这是一个简单的代码

class A {
    int i=2;
    void display() {
        System.out.println("display method of A");
    }
}

class B extends A {
    int i=1;
    void display() {
        System.out.println("display method of B");
    }
}

public class M {
    public static void main(String[] arg) {
        A a=new A();
        System.out.println(a.i);  
        a.display();

        a=new B();
        System.out.println(a.i);
        a.display();
    }
}
开/p: 2
     A的显示方法
     2
     B的显示方法

理解部分:首先声明“A”类型的引用变量“a”,它引用“A”的对象。当程序打印“ai”时,它会打印 A 的变量“i”,当 display 被调用为 a.display() 时,它会调用 A 类的 display。到这里为止都很好

问题部分:现在,当我分配 B 类型的引用变量“a”对象并打印 ai 时,它仍然会从 A 类(即 2)中打印“i”值。但是当我将显示函数称为 a.display() 时,它会调用方法“B”的显示

我的研究:每当我们使用引用变量访问成员变量时,都会检查引用变量的类型以访问它。当我们使用引用变量调用方法时,对象类型在运行时被评估(我认为这被称为多态性)并且根据对象类型调用特定的方法

我是对的还是涉及其他一些概念?而且我也想详细了解一下什么是多态性及其应用。如果你能向我推荐一些关于 OOP 和 java 基本概念的书,我会很高兴的

4

2 回答 2

2

那是因为多态只适用于实例方法而不是字段。因此,a.i(where ais of type A) 将始终打印2,无论它是否指向子类对象B

于 2013-07-06T15:28:27.483 回答
0

您对继承时应该做什么有误解。 extends是明智选择的保留字。B 扩展 A 的意义在于 B 是具有附加属性的 A 的子集。您不应该i在 B 中重新定义;A 应该处理i。通过i在子类中重新定义,您隐藏了超类的字段i(即使i引用不同的变量类型也是如此)。

    A a=new A();
    a.display();
    System.out.println(a.i);  //2 , since the i field in A is initialized to 2

    a=new B();
    a.display();
    System.out.println(a.i); //2, since the i field in A is initialized to 2

相反,如果您display()A,B中重新定义为:

  void display() 
  {
        System.out.println("Display method A/B: " + i);
  }

    A a=new A();
    a.display();  //Display method of A: 2 , since the i field in A is initialized to 2

    a=new B();
    a.display(); //Display method of B: 1, since the i field in B is initialized to 1

我认为 oracle 在他们的多态性教程中做得很好,但从继承开始可能会有所帮助。

于 2013-07-06T15:34:02.280 回答