目录
一、概念
多态可以理解为同一种事物的多种形态(Person p = new Student(),p既是一个具体的学生,又是一个人,出现了两种形态)。多态前提:
① 有继承或者实现关系
② 要有方法重写
③ 父类引用指向子类对象
多态的成员访问特点:非静态方法的运行看子类,其他都看父类。因为多态体现在对象调用方法多态,属性不是方法并没有多态。而静态方法属于类,不属于对象,也没有多态。
二、例子
public class Aniaml {
/**
* 对象属性--没有多态
*/
public String name = "动物";
/**
* 对象方法--存在多态
*/
public void run() {
System.out.println("动物奔跑....");
}
/**
* 静态方法属于类,不属于对象---没有多态
*/
public static void eat() {
System.out.println("动物吃东西...");
}
}
class Cat extends Aniaml{
public String name = "猫";
@Override
public void run() {
System.out.println("小猫奔跑....");
}
public static void eat() {
System.out.println("小猫吃东西...");
}
}
class Dog extends Aniaml {
@Override
public void run() {
System.out.println("小狗奔跑....");
}
public void houseKeep(){
System.out.println("小狗看家....");
}
}
class TestMethod {
public static void main(String[] args) {
Aniaml cat = new Cat();
Aniaml dog = new Dog();
/**
* 对象方法--存在多态
*/
// 打印结果:--> 小猫奔跑....
cat.run();
// 打印结果:--> 小狗奔跑....
dog.run();
/**
* 对象属性--没有多态
*/
// 打印结果:--> 动物
System.out.println(cat.name);
// 打印结果:--> 猫
System.out.println(((Cat) cat).name);
/**
* 类的静态方法--没有多态
*/
// 打印结果:--> 小猫吃东西...
Cat.eat();
// 打印结果:--> 动物吃东西...
Aniaml.eat();
}
}
三、转型
3.1 向上转型
当子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。
使用格式:
父类类型 变量名 = new 子类类型();
Person p = new Student();
好处:是隐藏了子类类型,提高了代码的扩展性
弊端:只能使用父类共性的内容,而无法使用子类特有功能,功能有限制
Animal a = new Cat();
//调用父类中共有方法run()
a.run();
3.2 向下转型
一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的!
使用格式:
子类类型变量名 = (子类类型) 父类类型的变量;
Animal p = new Cat();
//变量p 实际上指向Student对象
Cat cat = (Cat) p;
好处:可以使用子类特有功能
弊端:需要面对具体的子类对象,在向下转型时容易发生ClassCastException类型转换异常,在转换之前必须做类型判断
if(!a instanceof Cat){…}
什么时候使用向下转型?
当要使用子类特有功能时,就需要使用向下转型。
//向下转型
Animal p = new Dog();
//向下转型
Dog d = (Dog)p;
//调用狗类的houseKeep方法
d.houseKeep();