多态的定义
public class Test{
public static void main(String[] args) {
Mammal mammal1=new Whale();//自动类型转换:父类类型的变量指向其子类创建的对象 对象上转型 new Whale()上转型对象,类似于double price =9;由int 类型转化为double类型
mammal1.move();
Mammal mammal2=new Bat();
mammal2.move();两个状态:表面调用的是父类的方法因为创建的对象为mammal中的方法;但是执行时由于mammal2存的是子类创建的对象(存储的为子类的地址,jvm根据地址找到编译运行时的对象),所以执行时执行的是子类中的方法
}
}
分析:当把子类创建的对象直接赋给父类引用类型时,例如上例Test main方法中“Mammal mammal1 = new Whale();”, mammal1引用变量的编译时类型是Mammal,运行时类型是Whale,当程序运行时,该引用变量mammal1调用父类中被子类重写的方法时,其方法行为表现的是子类重写该方法后的行为特征,而不是父类方法的行为特征。
父类类型(比如Mammal)的变量(比如mammal1)指向子类创建的对象,使用该变量调用父类中一个被子类重写的方法(比如move方法),则父类中的方法呈现出不同的行为特征,这就是多态。
出现多态的原因
Java引用变量有两种类型,分别是编译时类型和运行时类型:编译时类型由声明该变量时使用的类型决定;运行时类型由实际赋给该变量的对象。如果编译时类型和运行时类型不一致,就可能出现所谓多态。
**编译时类型:**决定了其所修饰的变量名只能调用编译时类型中定义的或其继承过来方法。
**运行时类型:**决定了编译时类型修饰的变量名所调用的方法在程序执行过程中最终调用调用的方法。
注意:如果编译时类型和运行时类型相同,则一定不会出现多态;
如果编译时类型与运行时类型不相同,则不一定出现多态,前提是要出现子类对象的重写。
上转型对象:子类实例化的对象赋值给父类声明变量,则该对象称为上转型对象,这个过程称为对象上转型,对应于数据类型转换中的自动类型转换。
上转型对象不能调用子类新增的方法 和新增加的属性
其中weight和breathe方法都是子类中新的方法,所以上转型对象不能调用该方法
上转对象调用父类方法,如果该方法已被子类重写,则表现子类重写后的行为特征,否则表现父类的行为特征。
public class Mammal {
public void move() {
System.out.println("正在移动......");
}//父类
public void move() {
System.out.println("用鱼鳍移动......");
}//子类
public class Bat{
public static void main(String[] args) {
Mammal mammal=new Whale();
System.out .println(mammal.move);
此时出的将为"用鱼鳍移动",因为子类将该move方法重写,所以表现为子类重写后的行为特征;
使用上转型对象调用成员变量,无论该成员变量是否已经被子类覆盖,使用的都是父类中的成员变量:
public class Mammal {
public void move() {
System.out.println("正在移动......");
}
public String weight="1t";
}//父类的方法
System.out.println(new Whale().weight);
// Mammal mammal = new Whale();
// System.out.println(mammal.weight);
**所以问题:在上转型对象中如何实现调用子类新增的方法 和新增加的属性 **
此时我们需要采用对象下转型的方法
int price = (int)9.0;//类似于将double类型强制转换为int类型
Whale whale = (Whale)mammal;//其中whale为子类,mammal为父类
注意:下转型的前提是先出现上转型对象
Mammal mammal = new Mammal();//出现上转型对象
Whale whale = (Whale)mammal;//下转型对象
在多态的前提下,父类中被子类重写的方法没有必要有方法体
public abstract class Mammal {
public abstract void move() ;
public String weight="1t";
}
若一个类中有抽象方法则该类成为抽象类;
接口:若一个类中所有的方法均为抽象方法,那么这个抽象类称为接口。