类的多态性(JAVA)

简介: 类的多态性(JAVA)

多态

所有的OOP语言都会有三个特征:

    1. 封装(点击可跳转)
    2. 继承(点击可跳转)
    3. 多态

    多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。

    在java中要实现多态,必须要满足如下几个条件,缺一不可:

      1. 必须在继承体系下;
      2. 子类必须要对父类中方法进行重写 ;
      3. 通过父类的引用调用重写的方法。

      重写

      继承我们已经知道了,那我们面临的第一个问题就是什么是重写?

      重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值(返回类型满足父子关系也可以)和形参都不能改变。即外壳不变,核心重写!

      重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

      注:避免在构造方法中调用重写的方法。

      方法重写的规则:

        1. 子类在重写父类的方法时,一般必须与父类方法原型一致:方法名,参数列表要完全一致
        2. 被重写的方法返回值类型可以不同,但是必须是具有父子关系的
        3. 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected,父类被static、private修饰的方法、构造方法都不能被重写
        4. 重写的方法, 可以使用 @Override 注解来显式指定,有了这个注解能帮我们进行一些合法性校验。例如不小心将方法名字拼写错了 (比如写成 aet),那么此时编译器就会发现父类中没有 aet 方法,就会编译报错, 提示无法构成重写。

        此时我们已经满足两点了还差最后一点。而第三点是通过父类的引用调用重写的方法。而要实现这一点就必须进行向上转型。

        向上转型

        向上转型就是为了实现代码通过父类的引用调用重写的方法。向上转型其实很简单

        向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

        语法格式:父类类型 对象名 = new 子类类型()

        image.png

         向上转型的使用场景:

        • 直接赋值(上面的例子就是直接赋值)
        • 方法传参
        • 方法返回

        向上转型的优点:让代码实现更简单灵活。
        向上转型的缺陷:不能调用到子类特有的方法。

        使用了向上转型之后就可以通过父类的引用调用重写的方法,而不是重写方法的就没法调用

        classAnimal{
        publicStringname="花花";
        publicvoideat(){
        System.out.println(this.name+"正在吃饭");
            }
        }
        classDogextendsAnimal{
        @Overridepublicvoideat(){
        System.out.println(this.name+"在吃狗粮");
            }
        publicvoida(){
        System.out.println("hhh");
            }
        }
        publicclassTest {
        publicstaticvoidmain(String[] args) {
        Animaldog=newDog();
        dog.eat();
        //打印花花在吃狗粮Animaldog2=newAnimal();
        dog2.eat();
        //打印花花正在吃饭    }
        }

        image.gif

        image.png

         类的多态性例子:

        classAnimal{
        publicStringname="花花";
        publicvoideat(){
        System.out.println(this.name+"正在吃饭");
            }
        }
        classDogextendsAnimal{
        @Overridepublicvoideat(){
        System.out.println(this.name+"在吃狗粮");
            }
        }
        classCatextendsAnimal{
        @Overridepublicvoideat(){
        System.out.println(this.name+"在吃猫粮");
            }
        }
        publicclassTest {
        publicstaticvoidfun(Animalarr){
        arr.eat();
            }
        publicstaticvoidmain(String[] args) {
        //数组的每个成员都会发生向上转型Animal[] arr= {newDog(),
        newCat()};
        //此时就会发现调用同一个方法fun()会有两种结果fun(arr[0]);
        fun(arr[1]);
            }
        }

        image.gif

        image.png

        多态的优缺点

        • 能够降低代码的 "圈复杂度", 避免使用大量的 if - else;

        什么叫 "圈复杂度" ?

        圈复杂度是一种描述一段代码复杂程度的方式。一段代码如果平铺直叙,那么就比较简单容易理解。而如果有很多的条件分支或者循环语句,就认为理解起来更复杂;

        因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数,这个个数就称为 "圈复杂度"。如果一个方法的圈复杂度太高, 就需要考虑重构。

        • 可扩展能力更强;
        • 多态缺陷:代码的运行效率降低。
        目录
        相关文章
        |
        20小时前
        |
        安全 Java 开发者
        Java一分钟之-文件与目录操作:Path与Files类
        【5月更文挑战第13天】Java 7 引入`java.nio.file`包,`Path`和`Files`类提供文件和目录操作。`Path`表示路径,不可变。`Files`包含静态方法,支持创建、删除、读写文件和目录。常见问题包括:忽略异常处理、路径解析错误和权限问题。在使用时,注意异常处理、正确格式化路径和考虑权限,以保证代码稳定和安全。结合具体需求,这些方法将使文件操作更高效。
        11 2
        |
        20小时前
        |
        安全 Java 开发者
        Java一分钟之-Optional类:优雅处理null值
        【5月更文挑战第13天】Java 8的`Optional`类旨在减少`NullPointerException`,提供优雅的空值处理。本文介绍`Optional`的基本用法、创建、常见操作,以及如何避免错误,如直接调用`get()`、误用`if (optional != null)`检查和过度使用`Optional`。正确使用`Optional`能提高代码可读性和健壮性,建议结合实际场景灵活应用。
        17 3
        |
        20小时前
        |
        存储 Java ice
        【Java开发指南 | 第十六篇】Java数组及Arrays类
        【Java开发指南 | 第十六篇】Java数组及Arrays类
        8 3
        |
        20小时前
        |
        Java 编译器 ice
        【Java开发指南 | 第十五篇】Java Character 类、String 类
        【Java开发指南 | 第十五篇】Java Character 类、String 类
        13 1
        |
        20小时前
        |
        存储 Java ice
        【Java开发指南 | 第十四篇】Java Number类及Math类
        【Java开发指南 | 第十四篇】Java Number类及Math类
        10 1
        |
        20小时前
        |
        存储 缓存 Java
        【Java开发指南 | 第六篇】Java成员变量(实例变量)、 类变量(静态变量)
        【Java开发指南 | 第六篇】Java成员变量(实例变量)、 类变量(静态变量)
        9 2
        |
        20小时前
        |
        Java 编译器
        【Java开发指南 | 第一篇】类、对象基础概念及Java特征
        【Java开发指南 | 第一篇】类、对象基础概念及Java特征
        9 4
        |
        20小时前
        |
        安全 Java 数据安全/隐私保护
        Java一分钟之-Java反射机制:动态操作类与对象
        【5月更文挑战第12天】本文介绍了Java反射机制的基本用法,包括获取Class对象、创建对象、访问字段和调用方法。同时,讨论了常见的问题和易错点,如忽略访问权限检查、未捕获异常以及性能损耗,并提供了相应的避免策略。理解反射的工作原理和合理使用有助于提升代码灵活性,但需注意其带来的安全风险和性能影响。
        20 4
        |
        20小时前
        |
        安全 Java 调度
        Java一分钟:多线程编程初步:Thread类与Runnable接口
        【5月更文挑战第11天】本文介绍了Java中创建线程的两种方式:继承Thread类和实现Runnable接口,并讨论了多线程编程中的常见问题,如资源浪费、线程安全、死锁和优先级问题,提出了解决策略。示例展示了线程通信的生产者-消费者模型,强调理解和掌握线程操作对编写高效并发程序的重要性。
        44 3
        |
        20小时前
        |
        Java
        【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态
        【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态