Java多态
什么是多态
父类的变量指向子类创建的对象,使用该变量调用父类中被子类重写的方法,从而使父类的方法呈现出不同的行为特征,就是多态。
我们先看一个例子,我们定义一个父类叫 Father(),给它定义一个方法叫 work(); 然后再定义一个子类 Son,也给它定义一个方法也叫 work(),只不过父类的 work 的内容是上班,子类的 work 的内容是上学;重点来了,我们在一个main(); 中创建 Son 的一个对象并将地址赋值给子类变量 son,然后在创建 Father 的一个变量 father,并将 son 赋值给 father,输出 father 的work(); 和地址,我们会发现是 Son 创建的对象以及对象的方法,这种现象就是多态。相当于这样: int a=1; double b=a; 和这个思想很相似。
上例中注释掉的代码是源代码的简化,功能是一样的,都可以产生多态的。
为什么会产生多态
Java引用变量是有两种:编译时类型和运行时类型;编译时类型是由该变量声明时的声明类型决定的,运行时类型是由运行时变量被赋予的对象决定的,如果编译时类型与运行时类型不一致,则可能会出现所谓的多态(如上例);当然,如果子类没有重写父类的方法,则不会产生多态现象,即所谓的编译时类型与运行时类型不一致时不一定会产生多态;如下:
public class Father{
public void work(){
System.out.println("正在上班。。。");
}
}
public class Son extends Father{
}
public class Test{
public static void main(String[] args){
Father father = new Son();
father.work();
}
}
多态仅体现在方法上,不会体现在属性上
public class Father{
int age =48;
public void work(){
System.out.println("正在上班。。。");
}
}
public class Son extends Father{
int age = 12;
public void work(){
System.out.println("正在上学。。。");
}
}
public class Test{
public static void main(String[] args){
Father father = new Son();
father.work();
System.out.println(father.age);
}
}
其运行结果是: 正在上课。。。 (\n) 48 ;方法是子类的方法,而属性却是父类的属性,所以多态仅体现在方法上,不体现在属性上。
多态的作用 对象上转型与下转型
说到多态的作用我们不得不提两个过程和两个名词:对象上转型和对象下转型,上转型对象和下转型对象
对象上转型 和 上转型对象
子类实例化的对象赋值给父类声明的变量,则该对象称为上转型对象(即上例的 new Son();),这个过程称为对象上转型;对应于数据类型转换中的自动类型转换,即: int a=10; double b=a; 以上多态例子皆是,在这就不再举例了。
注意:上转型对象不能操作子类新增的成员变量;不能调用子类新增的方法!
public class Father{
int age =48;
public void work(){
System.out.println("正在上班。。。");
}
}
public class Son extends Father{
int age = 12;
int studentID = 111;
public void work(){
System.out.println("正在上学。。。");
}
public void readBook(){
System.out.println("正在读书。。。");
}
}
public class Test{
public static void main(String[] args){
Father father = new Son();
father.work();
father.readBook(); //这里报错,因为无法调用
System.out.println(father.age);
System.out.println(father.studentID); //这里也报错,同理也无法调用
}
}
对象下转型 和 下转型对象
可以通过对象下转型将上转型对象再强制转换为创建该对象的子类类型的对象,即将上转型对象还原为子类对象,对应于数据中的强制类型转换,即: int a=10; double b=a; int c=(int)b;
public class Father{
int age =48;
public void work(){
System.out.println("正在上班。。。");
}
}
public class Son extends Father{
int age = 12;
int studentID = 111;
public void work(){
System.out.println("正在上学。。。");
}
public void readBook(){
System.out.println("正在读书。。。");
}
}
public class Test{
public static void main(String[] args){
Father father = new Son();
Son son = (Son)father; //对象下转型
son.work();
son.readBook(); //可以使用
System.out.println(son.age);
System.out.println(son.studentID); //可以使用
//Father fa = new Father();
// son = (Son)fa; 错误,不被允许
}
}
输出的结果为:
正在上学。。。
正在读书。。。
12
111
还原后的对象又具备了子类所有属性和功能,既可以操作子类中继承或新增的成员变量;又可以调用子类中继承或新增的方法
注意:不可以将父类创建的对象通过强制类型转换赋值给子类声明的变量!
可以理解为狗为哺乳动物,但哺乳动物不是狗。