同一个引用类型,使用不同的实例而执行不同操作就是多态;方法重写是实现多态的基础
多态
左边是父类的引用,右边是他真正实例化是子类对象。如果在cat中重写了pet的方法,那么cat调用此方法是使用的是重写的方法。
Pet cat=new Cat();//从小范围转换到大范围的类自动转换,如果cat.Cat里的其中一个特有方法的话,会出现报错具体代码
左边限制了cat的属性和方法范围,因为引用的是父类,所以对象.属性或者方法所能使用的也只是父类的方法和属性,如果想要获得子类属性,那么需要向下转换
例如
T1 t1=new T2();
t1.setName("2");
t1.w();//这行代码是找不到此方法的,因为建立t1时,虽然建立的是T2的对象,但是拥有的属性和方法是T1的,w()方法是属于T2的。
t1.show();
T2 t2=new T2();
t2.setColor("red");
t2.setName("23");
t2.show();
t2.w(); //这行代码没有问题,因为t2是依据T2所建立的对象,所以可以直接使用T2的方法和属性。
Cat cat1=(Cat)cat;//强制转换,从大范围到小范围的类:cat1是Pet的子类对象,但是cat虽然也是,但是是依靠pet建立的,所以无法发生强制转换。
相当于吧单独创建对象引入Cat子类的独有属性或者方法,并且获得之前在cat里定义的属性,以免代码的重复使用。而且想要向下转型,必须之前有相应的向上转型,否则两个没有关系的类对象发生强制转换,会发生异常。
例如T1为父类,T2 为子类
T1 t1=new T2();
T2 t2=(T2)t1;//强制转换,t1虽然是T2的对象,但他的属性仍然是依靠T1建立的,强制转换之后,就拥有了T2的属性和方法。
t2.w();
目的:
多态性有什么用?对于对象多态性其本质是根据实例化对象所在的类是否重写了父类中的指定方法来决定最终执行的方法体,这样进行转型的意义是什么?
在链表操作中由于数据类型不统一,所以需要重复定义多个链表,那么通过对象的向上转型可以轻松的实现参数统一。例如如果一个个去创建子类对象进行接受,要写几百个子类运用同一种运行模式,但是向上转型可以通过一个参数类型就可以接受所有的子类对象。所以可以减少代码冗余。
例
1.使用父类作为方法的形参 实现多态
需求:动物医生 给不同的动物看病
如果不是用多态的话,那么有多少个动物就要写多少次方法,所以当我使用多态时,只需要改变输入的参数值:即建立子类对象后将对象名作为参数,运用同样医生类中的同一种方法即可。
简单工厂:
例如:.使用父类作为方法的返回值+简单工厂 实现多态
需求: 公司需求一批衣服
1.衬衣
2.西服
3.羽绒服
衣服类(父类)
子类: 衬衣 西服 羽绒服
服装工厂类: 根据用户的需求制造不同的衣服
测试类
选择
1.衬衣
2.西服
3.羽绒服
步骤:1.建立抽象父类衣服,提供抽象方法; //如果用建立对象一个一个去匹配的话,当子类很多的情况下,那么代码会非常的多,所以
2.建立衬衣,西服,和羽绒服等衣服的子类,重写抽象方法,输出用户想要的输出; 再建立简单工厂类,将用户去选择什么样的衣服交给工厂去做。详细代码见 3.建立简单工厂类,选择要生产的衣服 . day17/src/td2
4.建立测试类
instanceof:
1.建立一个抽象类Anmial类,建立一个healing(治疗)方法(抽象方法)
2.建立一个猫类和狗类,两者都需要重写方法,即重写自我治疗的方法,然后分别给猫类和狗类创建属于自己的方法,如猫类上树,狗类游泳
3.建立一个test类代码如下
public class Test{
public static void main(String[] args){
Animal[] animals=new Animal[4];
Dog dog =new Dog();
Cat cat =new Cat();
animals[0]=cat;
animals[1]=dog;
Dog dog1= new Dog90;
animalsp[2]=dog1; //建立一个数组,拥有三个元素,一个猫类对象,2个狗类对象和一个控制;
for(Ainmal animal:animals){//遍历这个数组,使用对象数组
//打印猫上树
Cat cat=animal;
cat.swim();
//如果只是这样运行会报错,因为如果输入的是狗类,那么狗类无法转换成为猫类,那么报错。所以这里需要判断
所以代码应该这么写
//打印猫上树
// 对象 判断语句 类型: 这句话的意思是,如果这个元素即对象的类是Cat的类,那么输出为true
if(animal instanceof Cat){
Cat cat1=animal;
cat.gouptree();
}
elseif (animal instanceof Dog){
Dog dog2=animal;
dog2.swim;
}
这样的话无论是狗还是猫都可以输出对应方法;
}
//但是如果我在if之前加入了一个animal.healing();,会发生报错,报错原因是因为我在打印数组元素是,对应序号为012的都没问题,但是对应序号为3的数组元素是一个null,而null是没有方法的所以会报错,所以一定要判断。
}
}
注意:使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系)