导引
面向对象程序设计的三大特性:继承性,封装性,多态性。
阅读本文前,依然需要思考这些问题,并带着它们阅读:
什么是多态性?
强调:不要在程序当中使用同名的成员域。这不仅与多态性无关,还会造成错误。
1.静态多态性
静态多态性指的是同一个类当中,同名的方法在功能上的重载(overload),既可以是成员方法的多态,也可以是构造方法的多态。
我们来看一个例子:(类似的例子详见雍俊海《Java程序设计教程》)
package whatever;
class J_Student{
public int m_id;
public int m_age;
public J_Student()
{
mb_setData(2008010400,19);
}//构造方法形态1
public J_Student(int id,int age)
{
mb_setData(id,age);
}//构造方法形态2
public void mb_setData(int id,int age)
{
m_id=id;
m_age=age;
}//mb_setData形态1
public void mb_setData(int id)
{
m_id=id;
}//mb_setData形态2
}
public class J_Teacher {
public static void main(String[] args)
{
J_Student jack=new J_Student();
jack.mb_setData(2008010408);
J_Student lisa=new J_Student(2008010428,18);
J_Student rocky=new J_Student();
rocky.mb_setData(2008010418, 17);
System.out.println("jack"+jack.m_id+"\nlisa"+lisa.m_id+"\nrocky"+rocky.m_id);
}
}
在这个例子当中,我们看到,构造方法 J_Student()和成员方法mb_setData()分别被赋予了两个参数表不同的形态。这两个形态的方法在被调用时会依照自身的参数表要求实参,一旦匹配便调用对应的方法。
输出结果:
jack2008010408
lisa2008010428
rocky2008010418
2.动态多态性
动态多态性指的是在子类和父类的类体当中均定义了具有基本相同声明的非静态成员方法,即不含有static修饰词的。
J_Employee.java
package whatever;
public class J_Employee {
public int workYear;
public J_Employee()
{
workYear=1;
}
public void mb_printInfo()
{
System.out.println("该职工的工作年限"+workYear);
}
}
J_Teacher.java
package whatever;
public class J_Teacher extends J_Employee {
public int classHour;
public J_Teacher()
{
classHour=96;
}
public void mb_printInfo()
{
System.out.println("该教师的工作年限为"+workYear);
System.out.println("该教师授课的课时"+classHour);
}
public static void main(String[] args)
{
J_Employee a= new J_Employee();
a.mb_printInfo();
a= new J_Teacher();
a.mb_printInfo();
}
}
编译结果:
该职工的工作年限1
该教师的工作年限为1
该教师授课的课时96
在这个例程当中,对于实例对象a调用过两次a.mb_printInfo()
第一次由于a是父类类型,只有一个成员域,调用的a.mb_printInfo()也是父类中的成员方法,只输出工作年限;第二次a已经由父类型被冲去为子类型,调用a.mb_printInfo()则作为子类中的成员方法,输出两个信息款。
在动态多态性当中,上述的mb_printInfo()成员方法发生了覆盖(override):
覆盖:子类的成员方法与父类声明基本一致的,此时子类的成员方法往往涵盖了父类中同名成员方法的操作,并包含独特的其他操作。称子类成员方法覆盖父类同名成员方法。
由于覆盖的存在,对于子类实例对象,Java虚拟机往往屏蔽了父类的同名成员方法。可以采用下面的方法越过子类覆盖访问父类类型。
1.访问父类成员域:super.xxx
2.访问父类的成员方法:super.method(xxx)
3.访问父类的构造方法:
在子类的构造方法的第一条语句调用其父类的构造方法,如:
super(父类构造方法参数表)
这样使得子类的构造方法具有了动态多态性
注意:动态多态性仅适用于非静态成员方法。