• Java中什么是多态?多态的优势和劣势是什么?





    在这里插入图片描述


    🍓🍓什么是多态?

    在编程语言和类型论中,多态(英语:polymorphism)指为不同数据类型的实体提供统一的接口。 多态类型(英语:polymorphic type)可以将自身所支持的操作套用到其它类型的值上。

    面向对象的三大特征:封装性、继承性、多态性,多态性就是多态,多态是在封装的升华,可以说没有封装就么有多态。

    extends继承或者implements实现,无论是类与类之间的继承、类与接口之间的实现还是接口与接口间的继承,反正总会出现上下的层次关系,这种关系的产生就是多态性出现的前提。

    为了更好的明白什么是多态,来个小demo吧!



    🍓🍓多态demo

    场景:有学生、老师、超级管理员,难道每一个都要重复写吗,这个岂不是很繁琐,维护起来很困难,若干年后当做diamagnetic重构的时候可能你都不想看你的代码了吧,应该是真的很繁琐,很复杂。

    下面我们将创建三个子类【Student、Teacher、Administrator】和一个父类【Person】以及一个测试函数


    父类,包含普通的变量和一个show方法。

    Person.java

    package DT.demo1;
    
    public class Person {
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
    
        public void show(){
            System.out.println(name+","+age+"展示");
        }
    }
    
    • 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

    学生类,继承父类属性和方法并重写父类show方法

    Student.java

    package DT.demo1;
    
    public class Student extends Person{
        @Override
        public void show() {
            System.out.println("学生的信息"+getName()+","+getAge());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    老师类,继承父类属性和方法并重写父类show方法

    Teacher.java

    package DT.demo1;
    
    public class Teacher extends Person{
        @Override
        public void show() {
            System.out.println("老师的信息"+getName()+","+getAge());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    超级管理员类,继承父类属性和方法并重写父类show方法
    Administrtors.java

    package DT.demo1;
    
    public class Administrtors extends Person{
        @Override
        public void show() {
            System.out.println("管理员的信息"+getName()+","+getAge());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    为了不需要重写我们只需要new出想要的对象然后传入即可。这样就算后面需要添加更多类型的用户也只需要new出对象,控制传入register的参数即可。注意因为main函数是static的,所以下面的register也必须是static类型的。

    Test.java

    package DT.demo1;
    
    public class Test{
        public static void main(String[] args) {
            Student student=new Student();
            student.setName("张三");
            student.setAge(20);
    
            Teacher teacher=new Teacher();
            teacher.setName("李四");
            teacher.setAge(22);
    
            Administrtors admin=new Administrtors();
            admin.setName("不良使");
            admin.setAge(18);
    
    
            register(student);
            register(teacher);
            register(admin);
    
    
    
        }
         public static void register(Person p){
            p.show();
         }
    }
    
    
    • 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

    在这里插入图片描述



    🍓🍓Java多态优势是什么

    为了考虑到篇幅和耗时,我们将所有的类写到一个类里面。注意,平时尽量不要这么操作,这里只是为了单纯的图快。
    Test.java

    package DT.demo2;
    
    
    // todo  为了方便查看就不把每一个类分开写了      下面都写到这一个Test.java  文件中
    public class Test {
        public static void main(String[] args) {
            // todo  多态方式创建对象     格式  :   Fu fu = new Zi();
            Animal animal=new Cat();
            //  todo  多态方式调用成员变量,编译看左边,运行也看左边
            //  *   编译看左边  ,  javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败
            //  *   运行看左边  ,  javac编译的时候实际获取的是左边父类中成员变量的值
            System.out.println(animal.name);  // todo  动物
    
    
    
    
            //   调用成员方法     编译看左边,运行看右边
            //  *   编译看左边  ,  javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败
            //  *   运行看左边  ,  javac编译的时候实际上运行的是子类中的方法
            animal.show();   // todo   Cat的show()方法
    
    
    
    
            // 理解
            Animal animal1=new Dog();
            //现在用animal1是Animal类型,都会默认从Animal这个类中去找
        }
    }
    
    class Animal{
        String name="动物";
        public void show(){
            System.out.println("Animal的show()方法");
        }
    }
    
    class Cat extends Animal{
        String name="猫";
    
        @Override
        public void show() {
            System.out.println("Cat的show()方法");
        }
    }
    
    class Dog extends Animal{
        String name="狗";
    
        @Override
        public void show() {
            System.out.println("Dog的show()方法");
        }
    }
    
    
    • 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
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    🥭🥭 1、

    在多态的形式下,右边的对象可以实现解耦合,便于扩展和维护

    例如:

    Person person = new Student();
    person.work();  //  多态new出来的对象调用woek方法
    
    • 1
    • 2

    但是当业务发生了变化时,我需要一个新对象【可以是老师、助教等,但是必须是Person的子类】 只需要修改 new Student();即可


    🥭🥭 2、
    定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现了多态的扩展性于遍历

    任何事物都不是完美无缺的,说完多态的优势,下面我们就来看看多态的劣势吧。



    🍓🍓Java多态劣势是什么

    不能使用子类的特定功能。

    嗯~,其实多态的劣势来源于多态的优势。为什么不修改呢,因为两者是并生的,而多态的优势 > 多态的劣势。任何专业术语,语言特性以及框架的出现都是为了方便性,所以~,你们明白的。

    下面来看看多态的劣势吧!

    在这里插入图片描述
    我们可以发现animal对象没有找到lookHome()这个方法,是不是很好奇,我明明new的是子类的Dog的对象,为什么Dog类中的方法却不能调用了呢?

    🌹🌹解析:

    多态new出来的对象,在调用成员方法和变量的调用和一般常规new出来的对象有些许不同。

    变量调用: 编译看左边,运行看左边

    🍎🍎编译看左边 , javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败
    🍎🍎运行看左边 , javac编译的时候实际获取的是左边父类中成员变量的值


    方法调用: 编译看左边,运行看右边

    🍎🍎编译看左边 , javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败
    🍎🍎运行看左边 , javac编译的时候实际上运行的是子类中的方法

    产生原因: 多态new出来的对象方法调用 编译看左边,运行看右边 。而父类没有这个方法,所以new出来的对象自然找不到。承受的范围大了。

    解决方案: 向下转型就行了,但是需要注意的是向下转型是不可以随便转的,佛则会报错。



    Test.java

    package DT.demo3;
    
    public class Test {
        public static void main(String[] args) {
            //   堕胎方式创建对象
            Animal animal=new Dog();
            Dog dog=(Dog)animal;
            dog.lookHome();
        }
    }
    class Animal{
        public void eat(){
            System.out.println("动物在吃饭");
        }
    }
    class Dog extends Animal{
        // 继承重写父类Animal的eat方法
        @Override
        public void eat() {
            System.out.println("够吃骨头");
        }
        // 狗自带方法,父类没有
        public void lookHome(){
            System.out.println("狗看家");
        }
    }
    
    
    class Cat extends Animal{
        // 继承重写父类Animal的eat方法
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
    
        // 猫自带方法,父类没有
        public void catchMouse(){
            System.out.println("猫抓老鼠");
        }
    }
    
    • 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
    • 39
    • 40

    在这里插入图片描述
    在这里插入图片描述







    觉得有用的可以给个三连,关注一波!!!带你了解更多的Java小知识

  • 相关阅读:
    CSS基础选择器
    如何准备好一场vue面试
    简单查找操作
    计讯物联5G RedCap网关TG463化繁为简,推动5G赋能千行百业
    MATLAB循环类型
    计算机组成原理
    【开发环境】(阿里云分布式文件系统)对象存储OSS 服务配置
    MySQL高级语句(二)
    JS最新的关键字和保留字
    JAVA毕业设计供求信息网计算机源码+lw文档+系统+调试部署+数据库
  • 原文地址:https://blog.csdn.net/qq_46906413/article/details/126078076