• 面向对象的三大特性之多态


    今天给大家总结介绍一下面向对象的三大特性之一的多态。



    多态:

    概念:同样的方法,在使用不同的对象调用时,表示出不同的行为称之为多态(Java中的多态实现依赖于继承和方法重写)。

    若我们理解不清楚,可以通过下面这个例子帮助记忆:
    在这里插入图片描述

    打印机为父类,它有彩色打印机和黑白打印机两个子类,使用彩色打印机对象调用print方法打印出来的是彩色图片,使用黑白打印机对象调用print方法打印出来的是黑白照片。简言之:多态性就是同一件事情(行为/方法),发生在不同的对象身上,表现出不同的结果。


    1.多态的向上转型

    向上转型发生的位置

    下面的例子以Animal为父类、Dog、Cat继承Animal为子类代码如下:

    package Java_3;
    
    //父类
    public class Animal {
        String name;
        int age;
        
        public Animal(String  name, int age) {
            this.name = name;
            this.age = age;
        }
        
        public void eat() {
            System.out.println(this.name + "在吃东西");
        }
    }
    
    //子类dog
    class Dog extends Animal {
        public Dog(String name, int age) {
            super(name, age);
        }
        
        public void eat() {
            System.out.println(this.name+"吃狗粮");
        }
    }
    
    //子类cat
    class Cat extends Animal {
        public Cat(String name, int age) {
            super(name, age);
        }
        
        public void eat() {
            System.out.println(this.name+"吃猫粮");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    a.直接赋值:

    父类名称 父类引用 = new 子类实例();
    Animal animal = new Dog();

    b.方法传参:

        public static void main(String[] args) {
    
            Dog dog=new Dog("哈巴狗",6);
            Cat cat=new Cat("加菲猫",5);
            fun(dog);
            fun(cat);
        }
    
        public static void fun(Animal animal){
            animal.eat();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    形参为父类引用,根据传入的子类对象的不同,表现出来的eat方法就不同。

    c.方法的返回值:

    下面的方法虽然它要求返回的是一个Animal对象,但我们可以以它的子类为返回结果。

        public static Animal buyAnimal(String name) {
            if (name.equals("狗")) {
                return new Dog("狗", 1);
            } else if (name.equals("猫")) {
                return new Cat("猫", 1);
            } else {
                return null;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    向上转型的好处

    a.参数统一化:

    假设现在要求实现一个方法,可以接收所有的Animal以及其子类的对象,调用eat方法。假设没有向上转型,只能当前类型的引用指向当前类型,那么有多少个子类我们就需要实现多少个eat方法;若有了向上转型,则只需要在方法形参规定父类的引用,所有该类的子类对象都能使用父类引用来接收,这时只需要写一个方法就行了。

    b.方便子类进行扩展:

    假设我现在要调用每个子类的方法:

    不使用向上转型:

    如果我增加了一个子类,则我需要重新new一个子类,在animal数组里加上该子类的对于字符串,在增强for循环里面需要重新再加上一个if else语句。

        public static void main(String[] args) {
    
            Dog dog = new Dog("哈巴狗", 6);
            Cat cat = new Cat("加菲猫",2);
            String[] animal={"Dog"};
            for(String str :animal){
                if(str.equals("Dog")){
                    dog.eat();
                }
                else if(str.equals("Cat")){
                    cat.eat();
                }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用向上转型:

    如果我增加了一个子类,我只需要在animal数组里面再new一个就行了。

        public static void main(String[] args) {
            
            Animal[] animal={new Dog("哈巴狗",1),new Cat("加菲猫",1)};
            for(Animal a :animal){
                a.eat();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.多态的向下转型

    Aniaml animal = new Dog();
    animal这个引用只能访问父类中有的属性和方法
    若此时要访问子类Dog中独有的属性和方法,就需要发生向下转型。

    向下转型的实现操作:

            Animal animal = new Dog("哈巴狗", 6);
            //使用instanceof关键字可以判断当前animal的引用是否指向Dog类实例
            if (animal instanceof Dog) {
                Dog dog = (Dog) animal;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    向下转型注意事项:

    1.要想发生向下转型,必须首先先进行向上转型。
    2.类型强转有风险,不能将毫无关系的两个类之间进行强转。

  • 相关阅读:
    QGraphicsItem图元坐标和在场景中的坐标(六)
    java比较两个ArrayList,得出两者中的不同元素
    【洛谷 P1591】阶乘数码 题解(模拟+高精度)
    快狗打车明日香港上市:年运营亏损超3亿 市场反应平淡
    CANopen权威指南【CAN总线协议】
    软考高级之系统架构设计师系列【2】考试说明及考点分析
    Prometheus Operator 与 kube-prometheus 之一-简介
    【python笔记】第六节 序列类型常用方法
    【软考系统架构设计师】2023年系统架构师冲刺模拟习题之《软件工程》
    数据探索电商平台用户行为流失分析
  • 原文地址:https://blog.csdn.net/qq_53130059/article/details/126874298