多态是面向对象程序设计的三大支柱之一,它的重要性不言而喻。用生活中简单的话来理解,多态就是做一件事情由不同的人去做,有不同的实现方式。
类型转换
cast 强制类型转换
upcasting 向上转型:将子类对象直接赋给父类引用(内容不变,多余的内容被扔掉)
<1>向上转型不需要强制类型转换
<2>向上转型后父类不能调用自己子类的方法
<3>父类引用或调用的方法是子类的方法
public class An {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();//狗吃肉
Animal a = d;//向上转型
a.eat();//狗吃肉
//a.todo(); 会报错,因为Animal类中没有todo方法,被扔掉了
}
}
class Animal {
public void eat() {
System.out.println("动物吃饭");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗吃肉");
}
public void todo() {
System.out.println("狗看家");
}
}
downcasting 向下转型:把指向子类对象的父类引用赋给子类引用(要强制转型)
<1>如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。
Dog d = new Dog();
Animal a = d;
d=(Dog)a;
d.todo();
<2>如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。
/* 编译无报错,但运行时出现java.lang.ClassCastException错误*/
Animal a = new Animal();
Dog d=(Dog)a;
d.todo();
它可以使用instanceof来避免出错此类错误。
h2 instanceof Animal 判断h2是不是Animal类型
Animal a = new Animal();
if(a instanceof Dog) {
Dog d =(Dog) a;
d.todo();
}
else System.out.println("...");
多态
继承关系使一个子类继承父类的特征,并且附加一些新特征。子类是父类的特殊化,每个子类的实例都是其父类的实例,但是反过来就不成立。
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。
多态存在的三个条件:
1.继承或者接口实现的关系
2.方法重写
3.父类引用指向子类对象:Parent p = new Child();
多态的成员访问特点
1.成员变量:编译看父类,运行看父类
2.成员方法:编译看父类,运行看子类
多态的作用:消除了类之间的耦合关系,大大提高了程序的可扩展性和可维护性。
多态的弊端:没有办法访问子类的特有成员
多态的使用场景:可以作为方法的参数和返回值进行使用,可以提高代码的拓展性。
多态的实现举例
class Animal {
int age=2;
public void eat() {
System.out.println("动物吃饭");
}
}
class Dog extends Animal{
int age=5;
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Animal{
int age=6;
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Demo {
public static void main(String[] args) {
//父类引用指向子类对象
Animal dog=new Dog();
Animal cat=new Cat();
//成员变量:访问父类的成员变量
System.out.println(dog.age);//2
System.out.println(cat.age);//2
//对象在不同的上下文,呈现不同的形式,通过继承链和向上转型实现多态
dog.eat();//狗吃肉
cat.eat();//猫吃鱼
Dog d=new Dog();
Cat c=new Cat();
method(d);//狗吃肉
method(c);//猫吃鱼
}
public static void method(Animal a) {
a.eat();
}
}