多态:同类型的对象执行同一个行为,会表现出不同的行为特征(父类引用子类的对象)
多态的常见形式: 父类类型 对象名称 = new 子类构造器;
接口 对象名称 = new 实现类构造器;
多态中成员访问特点:
- 方法调用:编译看左边,运行看右边。
- 变量调用:编译看左边,运行也看左边(多态注重行为多态)。
多态的前提:
有继承/实现关系;有父类引用指向子类的对象;有方法重写。
多态的优势:
- ?在多态形势下,右边对象可以实现解耦合,便于扩展和维护? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Aimal a = new Dog();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? a.run();//后续业务行为随对象而变,后续代码无需修改
- 在定义方法的时候,使用父类型作为参考,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利。
多态先会产行的一个问题?
多态下不能使用子类的独有功能
多态下引用数据类型的类型转换?
- ?自动类型转换(从子到父);子类对象赋值给父类类型的变量指向。
- 强制类型转换(从父 到子) 。此时必须进行强制类型转换,子类? 对象变量 = (子类)父类类型的变量。
?作用:可以解决多态下的劣势,可以实现调用子类独有的功能
注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现classCastException
?
Animal t = new Tortoise();
Dog d = (Dog)t;//出现异常 ClassCastException
?Java建议强转转换前使用instanceof判断当前对象的真实类型,再进行强制转换。
变量名 instanceof真实类型
判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其于子类类型,是则返回true,不是返回false。
示例:
? ? ?---- 狗狗类
? ? ? ? 增加狗狗吃东西的方法
? ? ? ? ---- 企鹅类
? ? ? ? 增加企鹅吃东西的方法
? ? ? ? ---- 创建主人类
? ? ? ? 编写给狗狗喂东西的方法
? ? ? ? 编写给企鹅喂东西的方法
? ? ? ? ---- 编写测试方法
? ? ? ? 调用主人类给狗狗喂东西的方法
? ? ? ? 调用主人类给企鹅喂东西的方法
如果再领养XXX宠物,就需要给XXX喂食,怎么办?
? ? ? ? ---- 添加XXX类,继承Pet类,实现吃食方法
? ? ? ? ---- 修改Person类,添加给XXX喂食的方法 ———————————————— 版权声明:本文为CSDN博主「jason的java世界」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/flywithcan/article/details/122467678
/**
* @Auther: Curran
* @Date: 2022/5/4 - 05 - 04 - 19:34
* @Description: AnimalDemo
* @version: 1.0
*/
public abstract class Pet {
//吃东西
public abstract void feed();
public void show(){
System.out.println("show......");
}
}
/**
* @Auther: Curran
* @Date: 2022/5/4 - 05 - 04 - 19:34
* @Description: AnimalDemo
* @version: 1.0
*/
public class Dog extends Pet{
@Override
public void feed() {
System.out.println("狗在啃骨头");
}
public void Test(){
System.out.println("Test......");
}
}
/**
* @Auther: Curran
* @Date: 2022/5/4 - 05 - 04 - 19:34
* @Description: AnimalDemo
* @version: 1.0
*/
public class Penguin extends Pet{
@Override
public void feed() {
System.out.println("企鹅正在吃");
}
}
/**
* @Auther: Curran
* @Date: 2022/5/4 - 05 - 04 - 19:34
* @Description: AnimalDemo
* @version: 1.0
*/
public class Cat extends Pet{
@Override
public void feed() {
System.out.println("猫在吃鱼...");
}
}
/**
* g@Auther: Curran
* @Date: 2022/5/4 - 05 - 04 - 19:34
* @Description: AnimalDemo
* @version: 1.0
*/
/*
* 多态:
* 对应同一个指令(调用同一个名称的方法),不同的对象给予不同的反应(不同的方法实现)
* 规范(多态实现的前提):
* 1、必须要有继承关系
* 2、子类方法必须重写父类的方法
* 3、父类引用指向子类对象(子类实例)
* 多态的目的:
* 1、为了提高代码的扩展性和维护性
* 2、方便代码逻辑的编写
* 多态的两种表现形式:
* 1、父类作为方法的参数
* 2、父类作为方法的返回值类型
*
* 引用类型的转换跟基本数据类型的转换类似:
* 1、当父类需要转成子类的时候,要进行强制转换,但是在强制转换之前一定要先判断父类引用指向的子类对象到底是谁,
* 如果无法确定,在运行过程中可能出错
* 2、当子类需要向父类转换的时候,直接自动转换,不需要进行任何的判断。
*
* */
public class Person {
// public void feed(Dog dog){
// dog.feed();
// }
// public void feed(Penguin penguin){
// penguin.feed();
// }
public void feed(Pet pet){
pet.feed();
}
public Pet getPet(String typeId){
if (typeId.equals("0")){
return new Dog();
}else if (typeId.equals("1")){
return new Penguin();
}else{
return new Cat();
}
}
public static void main(String[] args) {
// Person person = new Person();
// Dog dog = new Dog();
// person.feed(dog);
// Penguin penguin = new Penguin();
// person.feed(penguin);
Person person = new Person();
Pet dog = new Dog();
person.feed(dog);
dog.show();
Pet penguin = new Penguin();
person.feed(penguin);
Cat cat = new Cat();
person.feed(cat);
Pet pet = person.getPet("1");
if (pet instanceof Dog){
System.out.println("领养的是狗");
}else if(pet instanceof Penguin){
System.out.println("领养的是企鹅");//仅供参考,违法的
}else if(pet instanceof Cat){
System.out.println("领养的是猫");
}
}
}
|