我对多态性概念感到困惑。请任何人帮助我。这是一个简单的代码
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的基本概念的书籍,我将非常感激。
答案 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()
中的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在tutorial on polymorphism中做得很好,但从inheritance开始可能会有所帮助。