多态-面向对象
1)多态概述
同类型的对象,执行同一个行为,会表现出不同的行为特征
即相同的行为,不同的实现
(1)多态的常见形式
父类类型 对象名称 = new 子类构造器;
//接口的多态
接口 对象名称 = new 实现类构造器;
(2)多态的前提
有父类引用指向子类对象;有继承/实现关系;有方法重写
(3)访问特点:编译看左,运行看右
(4)优势:
在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
定义方法的时候,使用父类型作为参数,该方法就可以接受这父类的一切子类对象,体现出多态的扩展性与便利。
2)静态多态(重载式多态:使用重载)
编译时,系统就能决定调用哪个方法
3)动态多态(重写式多态:使用动态绑定和重写)
运行中系统才能动态确定调用哪个方法
有继承才能有动态多态
//动态多态的几种表现形式:
Cat cat = new Cat();
cat.jiao();
//向上转型 父类的引用指向子类的实例
//向上转型后,子类特有的属性和方法都会丢失
//编译看左边数据类型,为Animal,Animal没有就会报错
//运行看右边,若重写了就运行重写了的方法,没有就运行父类Animal的方法
//这样写可以随时换右边对象
Animal cat1 = new Cat();
syso(cat1.Info);//会报错,子类独有,左边为Animal类型
cat1.test();//会报错,子类独有,左边为Animal类型
cat1.jiao();//重写了,运行时调用Cat类中的重写方法
cat1.eat();//没重写,运行调用父类方法
//此时cat1 属于什么类型? --Animal类型,但其真身为Cat类型
//向下转型 强制转换,也叫做类型还原 将父类类型对象转换为子类类型
Cat c = (Cat)cat1;
//向下转型后,子类特有的属性和方法就都可以使用了
syso(c.Info);//不会报错了
c.test();//也可以使用了
c.jiao();//重写了,运行时调用Cat类中的重写方法
c.eat();//没重写,运行调用父类方法
//这样语法不报错,但运行回出现ClassCastException类型转换异常
//类型还原----必须还原成真身
Dog c1 = (Dog)cat1;
c1.jiao();
//使用instanceof判断一个对象真身属于什么数据类型--避免类型转换异常(用的很少,了解)
if(cat1 instanceof Cat){
Cat cat = (Cat)cat1;
syso("真身是猫");
}else if(cat1 instanceof Dog){
Dog cat = (Dog)cat1;
syso("真身是狗");
}
//多态的应用--动态参数
//就是当方法的某个形式参数是一个引用的时候,与该引用兼容的任何对象都可以传递给方法,从而允许方法接收不同数据类型的形式参数
//通常使用父类作为形参
//在调用此方法时,传递此类型或者此类型的子类对象作为实参
//静态
public class Person{
public void lingyang(Dog dog){
syso("领养的狗");
}
public void lingyang(Cat cat){
syso("领养的猫");
}
}
//动态
public class Person{
public void lingyang(Animal animal){
syso("领养的是动物");
}
}
main:
Person p = new Person();
Dog d = new Dog();
p.lingyang(d);//传递过程 Animal annimal = new Dog();
public class Person{
public void lingyang(Animal animal){
if(animal instanceof Cat){
syso("领养猫");
}else if(animal instanceof Dog){
syso("领养狗");
}
}
}
//因为是可以兼容的任何对象,所以int也能传给Integer、object
public void test(object c){
syso("test");
}
int i=10;
test(i);//先将i转为Integer,再传给object c = intege i;
//异构数组 存储的真实类型不一样·
//父类类型对象数组 = 子类类型对象
Animal a = neW Animal();
Dog d = new Dog();
Cat c = new` Cat();
Animal[] animals = new Animal[]{a,c,d}

浙公网安备 33010602011771号