使用父类的地方都可以使用子类的对象,这就是通常所说的多态。简单来说,多态意味着父类型的变量可以引用子类型的对象。
比如 People a1=new Student(); 所有的学生是人,但不是所有人都是学生。
这就是多态。
2.多态转型 (1)向上转型:父类名称 变量名 = new 子类名称();
例如:People peo=new Student();
要注意的是,一旦向上转型为父类,那么就无法调用子类原本特有的方法。
如果需要调用,需要用对象的向下转型还原。
例如:
package Test;
public class Test {
public static void main(String[] args) {
People peo=new People();
peo.eat(); 输出为:吃
People peo1=new Student(); //向上转型
peo1.sleep(); //子类没有这个方法,向上找,调用的是父类的方法; 输出为:睡
peo1.smail();//共有的方法,new的是谁,调用的是谁; 输出为:笑嘻嘻
peo1.work();//子类特有的方法,会报错。此时要向下转型,变回子类对象。 报错
}
}
class People
{
public void smail() {
System.out.println("笑");
}
public void eat() {
System.out.println("吃");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Student extends People
{
public void smail() {
System.out.println("笑嘻嘻");
}
public void work() {
System.out.println("学习");
}
}
(2)向下转型
子类名称 变量名=(子类名称)父类的变量名
Sutdent stu=(Student) peo;
这样就可以调用子类的特定方法了。
比如在上端代码的基础上加上:
package Test;
public class Test {
public static void main(String[] args) {
People peo=new People();
peo.eat(); 输出为:吃
People peo1=new Student(); //向上转型
peo1.sleep(); //子类没有这个方法,向上找,调用的是父类的方法; 输出为:睡
peo1.smail();//共有的方法,new的是谁,调用的是谁; 输出为:笑嘻嘻
peo1.work();//子类特有的方法,会报错。此时要向下转型,变回子类对象。 报错
}
//新加
Student stu=(Student)peo1; //向下转型,把父类对象还原成本来的子类对象
stu.work(); //调用子类的特定方法 输出为:学习
}
class People
{
public void smail() {
System.out.println("笑");
}
public void eat() {
System.out.println("吃");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Student extends People
{
public void smail() {
System.out.println("笑嘻嘻");
}
public void work() {
System.out.println("学习");
}
}
- 访问成员变量的方式:
通过对象名访问成员变量,看等号左边是谁优先用谁,没有则向上找。 - 访问成员方法:
new的是谁调用谁的方法,没有就向上找。
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。
对于面向对象而已,多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。



