多态
- 多态的前提:继承
- 对象的多态:一个对象拥有多种形态,例如小明有学生形态,有人类形态
- 代码中体现多态性:其实就是一句话,父类引用指向子类对象
Person p = new Student();
- 上句是向上转型,一旦向上转型为父类,就无法调用子类原本特有的内容
- p就是Person类的实例对象,用p调用方法或属性 p. n 或p. add()等就是调用Person类的内容,和Student类无关
- 特例是:若Student类重写了Person类的方法,p调用该方法相当于调用Student类的方法
public class Person {
public int n = 0;
public void test2() {
System.out.println("test2_Person");
}
}
public class Student extends Person{
public int num = 1;
public int age = 1
public void test2() {
System.out.println("test2_Student");
}
public void test3(){
System.out.println("test3")
}
}
下述代码非常重要
public class Test2 {
public static void main(String[] args) {
Person p = new Student(); // 向上转型
p.test2(); // 子类重写了父类方法,所以调用的是子类方法
p.test3(); // 错误,p不可以调用Student类的方法
System.out.println(p.n); //属性不可被重写,所以调用的是父类属性
System.out.println(p.age); //报错,Person类和Object类没该属性
}
}
使用多态的好处
举例:
- 有一父类Employee员工类, n个子类讲师类,助教类,教授类等
- Employee有抽象方法work(),每个子类都重写work()
- 创建每个对象:
Employee one = new Teacher();
Employee two = new Assiatant();
Employee three = new Professor();
- 带来了统一性,每个对象都相当于一个类实例化来的,而且还有其特有的work方法
- 无论"="右边new的时候换成哪个子类对象,等号左边调用方法,属性都不会变化
- 每个对象都统一起来了,他们除了work之外都有相通的属性方法,比如身高,体重,专业等
上下转型
- 向上转型:其实就是多态写法,向上转型一定是安全的,
父类名称 对象名 = new 子类名称();
- 向下转型:还原向上转型
子类名称 对象名 = (子类名称)父类对象;
Animal animal = new Dog();
if (animal instanceof Dog){ // 看清大小写
Dog dog = (Dog) animal;
}
- 前提:
- 向上转型,只有向上转型后才可以使用向下转型
- 向下转型使用的子类名必须是向上转型的子类名
- 切记:下述代码错误
Animal animal = new Animal();
Dog dog = (Dog) animal; // 报错
Animal animal = new Cat();
Dog dog = (Dog) animal; // 报错
- 为什么要向下转型:当使用多态(向上转型)后,需要调用子类特有的方法
- 转型需要配合 instanceof 使用:
向上向下转型有什么意义?
- 当传入的参数不知道是什么类时,可以用最底层父类修饰:
public static void giveMeAPet(Animal animal){
if (animal instanceof Dog){
Dog dog = (Dog) animal;
dog.watchHouse;
}
if (animal instanceof Cat){
Cat cat = (Cat) animal;
cat.catchMouse;
}
}
构造方法用private修饰:
- 多用于单例模式
- 要实现单例,还需要:
private static Person person = new Person();
public static Single getInstance() {
return single;
}