07- 面向对象之多态

多态

需求分析

养了多只动物, 每一个动物生病之后, 需要提供相应的方法 ,

给宠物看病, 宠物越多, 方法越多 , 每添加一个宠物, 就需要添加一个方法

弊端: 频繁修改代码, 可扩展性和可维护性差

// 给狗看病的方法
public void cure(Dog dog){
    System.out.println("给"+dog.name+"看病 ");
}
// 给猫看病
public void cure(Cat cat){
    System.out.println("给"+cat.name+"看病 ");
}
//给猪看病
public void cure(Pig pig){
    System.out.println("给"+pig.name+"看病 ");
}

优化之后

// 给动物看病的方法
public void cure(Animal animal){
    System.out.println("给"+animal.name+"看病 ");
}

多态的使用

父类的变量 指向 子类的对象
Animal animal = new Dog();  // Dog dog = new Dog();

回顾基本数据类型

int a = 10;
long b = a;

作用案例

参数列表是父类的情况

Person person= new Person();

Dog dog = new Dog();
dog.name = "旺财";
// 人给动物看病
person.cure(dog);

Cat cat = new Cat();
cat.name = "Tom";
// 人给动物看病
person.cure(cat);

返回值为父类的情况(人去买宠物)

// 客户 需要告诉商家 要买什么宠物
public Animal sell(String type){
    if(type.equals("dog")){
        Dog dog = new Dog();
        dog.name = "来福";
        return dog;
    }else if(type.equals("cat")){
        Cat cat = new Cat();
        cat.name = "hello kitty";
        return cat;
    }else{
        Pig pig = new Pig();
        pig.name = "佩琪";
        return pig;
    }
}

优势好处

屏蔽子类之间的差异

可替换性

可扩充性

接口性

灵活性

简化性

多态注意事项

父类变量指向子类对象

儿子装爹案例

父亲 是 中医大夫

儿子 学习 西医

( 有人来看病- 该病人相信中医大夫, 但是恰好中医大夫不在家, 只有儿子在家 )

​ 儿子装爹

新建father类

package date0712;

/**
 * 中医大夫 (父亲)
 */
public class Father {
    // 姓名
    String name = "扁鹊";
    // 年龄
    int age = 100;
    // 工具包 = 针灸包
    String instrument = "acupuncture";
    // 爱好
    String hobby = "喝茶";
    // 有瓷器(父亲有 儿子没有)
    String china = "景德镇";

    // 娱乐活动
    public void play(){
        System.out.println("喝茶,看报,听曲 !");
    }

    // 看病的方法
    public void cure(){
        System.out.println("望闻问切 ");
        System.out.println("使用中药, 针灸 治疗");
    }
    // 把脉的方法 (父亲有 儿子没有 , 儿子会默认继承)
    public void pulse(){
        System.out.println("把脉");
    }
}

新建 son子类

package date0712;

/**
 * 西医 (儿子)
 */
public class Son extends Father{
    // 姓名
    String name = "扁小鹊";
    // 年龄
    int age = 25;
    // 工具包 = 针灸包
    String instrument = "手术刀";
    // 爱好
    String hobby = "刷抖音,玩游戏";
    // 电脑 (儿子有 父亲没有)
    String computer = "苹果";

    //  (父类有play 方法, 如果儿子自己没有play 默认继承父类的)
    // 方法重写  父类有该方法, 但是 儿子偏偏不喜欢 ()
    @Override
    public void play(){
        System.out.println("逛夜店, 蹦迪!");
    }
    // 看病的方法
    @Override
    public void cure(){
        System.out.println("听诊器 先进设备查一查 ");
        System.out.println("使用西药,做手术");
    }
    // 做手术  (儿子有 父亲没有)
    public void operate(){
        System.out.println("做手术");
    }
}

方法和属性的调用

public class Demo {
    public static void main(String[] args) {
        // 病人上门 找 中医 , 只有西医儿子在家
        // 儿子穿上父亲的衣服  模拟父亲的外貌
        Father father = new Son();

        System.out.println(father.name);
        System.out.println(father.age);
        System.out.println(father.instrument);
        System.out.println(father.hobby);
        System.out.println(father.china);
        /*
        对于属性  父亲有什么 , 儿子才能有什么 (儿子只能使用父亲有的东西)
        方法 父亲有什么方法, 儿子才能使用什么方法
         */
        // System.out.println(father.computer);  //报错

        father.pulse();
       //  father.operate();  // 手术方法 报错
       // 编译看左边  编译不报错, 需要看赋值号左侧 类型中有那些属性和方法
       // 运行看右边  当子类重写了父类的方法之后 , 运行实际对象重写之后的方法
        father.play();
        father.cure();
    }
}

编译看左边 编译不报错, 需要看赋值号左侧 类型中有那些属性和方法
运行看右边 当子类重写了父类的方法之后 , 运行实际对象重写之后的方法

对象的向上和向下转型

// 先卸下父亲的伪装 , 还原儿子的真面貌 , 才可以去调用儿子的属性和方法
Father father = new Son();
Son son = (Son) f1;

儿子 ==> 父亲 向上转型 (由小容器到大容器 ) 多态

父亲 ==> 儿子 向下转型 (由大容器到小容器) 需要先判断 然后在转型

instanceof

新建女儿类
public class Daughter extends Father{}
Father f1 = new Son();
Father f2 = new Daughter();
Son son = (Son) f1;
Daughter daughter = (Daughter) f2;
// 儿子和女儿之间不能 转换 (否则会报类型转换异常)
// java.lang.ClassCastException
避免类型转换异常
// 判断 f1 对象 是否可以转换为 Son 对象
System.out.println(f1 instanceof Son);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值