一、多态
- 什么是多态 ?
- 多态即同一个方法可以根据发送对象的不同而采用多种不同的行为方式!
- 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多!
- 多态存在的条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
- 注意点:多态是方法的多态,属性没有多态性!
首先,逐步解释什么是多态,多态的前提下一定要满足上面的三个条件!然后才能实现多态,现在用代码就行演示!
1、父类Pet(宠物)
package com.oop.demo08;
//父类宠物
public class Pet {
//看病类
public void toHospital(){ //这里定义了一个看病的方法 能让后面的子类进行重写!
System.out.println("宠物看病!");
}
}
2、子类Bird(小鸟)
package com.oop.demo08;
//子类鸟
public class Bird extends Pet{ //继承父类
//看病类 重写父类的方法
public void toHospital(){ //这里是重写了父类的方法!
System.out.println("小鸟看病!");
}
}
3、父类Dog(小狗)
package com.oop.demo08;
//子类狗
public class Dog extends Pet{ //继承父类
@Override //这里是重写了父类的方法!
public void toHospital() {
System.out.println("小狗看病!");
}
}
4、输出类Application(输出)
package com.oop.demo08;
//输出类 一个项目尽量只有一个main输出方法
public class Application {
public static void main(String[] args) {
//父类的引用指向子类对象! 前面是引用对象跟引用变量 后面是被引用的对象!
Pet pet; //这里实例化了父类 得出引用变量名pet
pet = new Bird(); //父类的引用指向了子类鸟 也就是会输出子类重写父类后的方法
pet.toHospital(); //会输出小鸟看病 因为被引用的是鸟类,也就是使用的是鸟类的方法!这就是多态
pet = new Dog(); //父类的引用指向了子类狗 也就是会输出子类重写父类后的方法
pet.toHospital();
}
}
总结: 综上,在输出来调用之前,必须要先实例化一个父类的对象,也就是 new一个父类的对象,将引用变量实例出来,然后再去就父类的指引,指向其他的子类,比如上面说到的 pet = new Bird(); 这里就是父类引用了子类的对象(类),然后输出的也是子类中重写后的方法!所以得出以下的结果!
- 结果
二、instanceof运算符
见名知意,就是一个运算符,返回的结果是true或者false,用来判断是否满足引用类型的转换!
- 直接在代码中便可以看到运行结果!
//输出类 一个项目尽量只有一个main输出方法
public class Application {
public static void main(String[] args) {
Object object = new Dog(); //object是当前类的祖先!
//以下是父子关系,由高到低!
//Object >>> Pet
//Object >>> Pet >>> Bird
//Object >>> Pet >>> Dog
System.out.println(object instanceof Pet); //返回结果true
System.out.println(object instanceof Object);//返回结果true
System.out.println(object instanceof Dog);//返回结果true
System.out.println(object instanceof Bird);//返回结果false,因为继承关系中Dog并没有他!
System.out.println("********************************");
Object object02 = new Pet();
System.out.println(object02 instanceof Pet); //返回结果true
System.out.println(object02 instanceof Object);//返回结果true
System.out.println(object02 instanceof Dog);//返回结果false,因为继承关系中并没有他,输出之后继承的只有他们两个!
System.out.println(object02 instanceof Bird);//返回结果false,因为继承关系中并没有他,输出之后继承的只有他们两个!
}
}
总结:在运行过程中,instanceof运算符会根据左右两边的值去判断是否存在继承关系,需要注意的是,当祖父类去比较父类的时候,子类跟他们构不成继承关系的,因为对比只有他们两个,所以子类会输出false!注意:对象的类型必须和instanceof后面的参数所指定的类有继承关系,否则会直接编译错误,比如:object instanceof String ,会直接报错!
三、引用类型转型(重点)
- 引用类型转换顾名思义,跟前面学期数据类型转换差不多,但是这个转换的注意点还是挺多的,转型分为向上转型跟向下转型!(左边是编译,右边是执行)
1、向上转型
- 向上转型后,父类无法使用子类独有的方法!即左边的对象引用右边的对象。
- 转型后的父类引用变量调用的方法是子类覆盖或者继承了父类的方法,不是父类的方法!
- 当父类的引用指向子类对象就称为向上转型,系统会自动进行类型转换!
2、向下转型
- 如果pet(父类)对象跟Dog对象 存在继承关系,则为true 然后执行以下
- 子类名 引用名 = (子类名) 父类名; 向下转换,强转换为子类!
//输出类 一个项目尽量只有一个main输出方法
public class Application {
public static void main(String[] args) {
//向上转型 多态中,父类的引用指向子类,系统会自动转型
Pet pet = new Dog();
pet.toHospital(); //输出小狗看病!
if (pet instanceof Dog){ //如果pet(父类)对象跟Dog对象 存在继承关系,则为true 然后执行以下
Dog dog = (Dog)pet; //向下转换,强转换为子类!
dog.Fly(); //执行小狗特有的方法!玩飞盘游戏!
}else if (pet instanceof Bird){ //如果pet(父类)对象跟Bird对象 不存在继承关系,则为false 然后执行以下
Bird bird = (Bird) pet; //向下转换,强转换为子类!
bird.Fei(); //执行小鸟特有的方法! 自由的飞翔!
}
}
}
结果如下:
总结:总的来说呢,就是强转类型的时候,一般配合instanceof运算符使用,然后进行判断是否可以进行强转换!输出结果可以跟代码一起参考!
注:文章仅做个人学习日记,不做学习建议,学习来源:狂神说