今天给大家总结介绍一下面向对象的三大特性之一的多态。
多态:
概念:同样的方法,在使用不同的对象调用时,表示出不同的行为称之为多态(Java中的多态实现依赖于继承和方法重写)。
若我们理解不清楚,可以通过下面这个例子帮助记忆:
打印机为父类,它有彩色打印机和黑白打印机两个子类,使用彩色打印机对象调用print方法打印出来的是彩色图片,使用黑白打印机对象调用print方法打印出来的是黑白照片。简言之:多态性就是同一件事情(行为/方法),发生在不同的对象身上,表现出不同的结果。
1.多态的向上转型
向上转型发生的位置
下面的例子以Animal为父类、Dog、Cat继承Animal为子类代码如下:
package Java_3;
//父类
public class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(this.name + "在吃东西");
}
}
//子类dog
class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println(this.name+"吃狗粮");
}
}
//子类cat
class Cat extends Animal {
public Cat(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println(this.name+"吃猫粮");
}
}
a.直接赋值:
父类名称 父类引用 = new 子类实例();
Animal animal = new Dog();
b.方法传参:
public static void main(String[] args) {
Dog dog=new Dog("哈巴狗",6);
Cat cat=new Cat("加菲猫",5);
fun(dog);
fun(cat);
}
public static void fun(Animal animal){
animal.eat();
}
形参为父类引用,根据传入的子类对象的不同,表现出来的eat方法就不同。
c.方法的返回值:
下面的方法虽然它要求返回的是一个Animal对象,但我们可以以它的子类为返回结果。
public static Animal buyAnimal(String name) {
if (name.equals("狗")) {
return new Dog("狗", 1);
} else if (name.equals("猫")) {
return new Cat("猫", 1);
} else {
return null;
}
}
向上转型的好处
a.参数统一化:
假设现在要求实现一个方法,可以接收所有的Animal以及其子类的对象,调用eat方法。假设没有向上转型,只能当前类型的引用指向当前类型,那么有多少个子类我们就需要实现多少个eat方法;若有了向上转型,则只需要在方法形参规定父类的引用,所有该类的子类对象都能使用父类引用来接收,这时只需要写一个方法就行了。
b.方便子类进行扩展:
假设我现在要调用每个子类的方法:
不使用向上转型:
如果我增加了一个子类,则我需要重新new一个子类,在animal数组里加上该子类的对于字符串,在增强for循环里面需要重新再加上一个if else语句。
public static void main(String[] args) {
Dog dog = new Dog("哈巴狗", 6);
Cat cat = new Cat("加菲猫",2);
String[] animal={"Dog"};
for(String str :animal){
if(str.equals("Dog")){
dog.eat();
}
else if(str.equals("Cat")){
cat.eat();
}
}
}
使用向上转型:
如果我增加了一个子类,我只需要在animal数组里面再new一个就行了。
public static void main(String[] args) {
Animal[] animal={new Dog("哈巴狗",1),new Cat("加菲猫",1)};
for(Animal a :animal){
a.eat();
}
}
}
2.多态的向下转型
Aniaml animal = new Dog();
animal这个引用只能访问父类中有的属性和方法
若此时要访问子类Dog中独有的属性和方法,就需要发生向下转型。
向下转型的实现操作:
Animal animal = new Dog("哈巴狗", 6);
//使用instanceof关键字可以判断当前animal的引用是否指向Dog类实例
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
}
向下转型注意事项:
1.要想发生向下转型,必须首先先进行向上转型。
2.类型强转有风险,不能将毫无关系的两个类之间进行强转。