java中的多态
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
本文为读
封装, 继承, 和多态是面向对象编程的三大特性, 而多态是其中相对比较难以理解的一种,特此介绍:
假设有两个类A和B,其中A为基类,B为A的子类,两个类都包含一个run()方法:
public class A{
public void run(){System.out.println("A");};
}
public class B extends A{
public void run(){System.out.println("B");}
}
我们可以通过一下方法得到一个B的对象:
A b=new B();
这时执行b.run();会输出什么呢? 很显然,我们期待的是"B",而实际上正确的输出也是"B". 同理,若此时还有一个继承自A的子类C,其中有一个run()方法:
public class C extends A{
public void run(){System.out.println("C");}
}
当我们通过以下方法创建一个C的对象并调用起run()方法:
A c=new C();
c.run();
执行的结果是"C".
这就是多态的作用:分离做什么和怎么做.虽然b和c都调用了相同名字的方法run(),但是JAVA却能够在运行时正确的调用其相应子类的方法,而不是其基类的方法.也就是说:b.run()或者c.run()仅仅是告诉b和c对象要执行一个名字叫run()的方法,但是具体要调用的到底是A,还是B和C中的run()方法实体,编程者无需指定,JAVA会在运行时动态的将正确的run()方法的实体绑定到run()的方法调用.然后就会产生正确的结果.这种绑定方法称作"运行时绑定"或者"动态绑定".
另外,在JAVA中除static和final方法以外其他方法都是动态绑定.由于private方法属于final方法,构造器方法是隐式的static方法,所以这两种方法不具有多态性,当执行上面的例子时,若run()方法是static的或者final的,则输出只会是"A".
任何对域,也就是成员变量的访问都不是多态的,因为访问是在编译期进行的.
多态(java描述)
一、多态的必要条件
常说的面向对象具有封装、继承、多态的特性。这三者其实是有先后关系的,往往谈多态都离不开继承。所以要实现多态性就必须存在着继承关系。在面向对象中,类是必不可少的东西。那么无论是变量多态还是方法多态也都离不了类的承载。
二、多态的实现
“多形性”(Polymorphism)从另一个角度将接口从具体的实施细节中分离出来,亦即实现了“是什么”与“怎样做”两个模块的分离(来自java编程思想第四版)。就我的理解就是将抽象和具体的分离。就好比我们工作中领导不会告诉你怎么去做,但是他会告诉你该做什么,至于你怎么去做,他不太关心。
从程序的角度理解,多态就是父类引用指向子类对象。那么通过父类的引用句柄调用方法时能产生不同的行为。我们以图形例子来描述:
class Shape {
void draw() {
}
void erase() {
}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
void erase() {
System.out.println("Circle.erase()");
}
}
class Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}
void erase() {
System.out.println("Square.erase()");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Triangle.draw()");
}
void erase() {
System.out.println("Triangle.erase()");
}
}
那么下面这段代码:
(1*)
Shape sh1=new Circle();
Shape sh2=new Square();
Shape sh3=new Triangle();
sh1.draw();
sh2.draw();
sh3.draw();
运行的结果应该是每个子类中的方法实现。按照字面理解这应该是错误的写法,因为不同的对象进行的赋值操作,并且Shape 的句柄应该只能操作Shape 中的方法。其实我们无需理会这些,因为它是面向对象的思想,这正是多态的一种表现。
现在我们增加需求:一个人画三角形,用程序描述。
按常规,我们会增加类Person,如下:
class Person{
void p_draw(Triangle tr){
tr.draw();
}
}
但如果我们需求发生变化:一个人画圆。
那我们的Person类又得重新设计并编写,利用多态我们改变程序:
class Person{
void p_draw(Shape sh){
sh.draw();
}
}