难以理解多态性

时间:2013-07-06 15:26:50

标签: java oop polymorphism

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

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();
    }
}
O/p: 2
     display method of A
     2
     display method of B

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

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

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

我是对还是涉及其他一些概念?我还想知道什么是多态性及其 应用程序 。如果您向我推荐一些关于OOP和java的基本概念的书籍,我将非常感激。

2 个答案:

答案 0 :(得分:2)

那是因为 Polymorphism 仅适用于实例方法而非字段。因此,a.i(其中a的类型为A)将始终打印2,无论它是否指向子类对象B

答案 1 :(得分:0)

你对继承中应该做的事情有误解。 extends是一个明智选择的保留词。 B扩展A的点是B表示具有附加属性的A的子集。你不应该在B中重新定义i; 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()中的AB将成为:

  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在tutorial on polymorphism中做得很好,但从inheritance开始可能会有所帮助。