目录
多态的理解
向上转型
向上转型的三种形式
动态绑定和静态绑定
方法的重写
进一步认识和理解多态
多态的优点
首页 Java java教程 Java面向对象之多态实例分析

Java面向对象之多态实例分析

Apr 19, 2023 pm 01:34 PM
java

    多态的理解

    什么是多态呢??从字面理解就是多种形态,也就是不同类实例化出来的对象调用同一种方法,也可以理解为不同类的对象经过同一种行为产生的状态是不同的,这就是多态。

    要想理解多态,我们必须要了解向上转型和重写这两个重点然后在来深刻理解多态这一概念,等看完向上转型与重写再来看多态的概念,你就会豁然开朗,一下就通透了不少。因为多态的条件就是向上转型,重写以及继承。

    向上转型

    首先多态的前提是继承,那既然是继承,那就肯定就有父类与子类这样的关系。

    我们再来回忆一下怎么创建子类对象和父类对象。

    class Animal{
        public String name;//名字
        public int age;
        public void eat() {
            System.out.println("我要吃饭!!!");
        }
        public void sleep() {
            System.out.println("我要睡觉!!!");
        }
    }
    class Cat extends Animal{
        public void mew() {
            System.out.println("喵喵喵!!!");
        }
    }
    public class TestDemo1 {
        public static void main(String[] args) {
             Cat cat =new Cat();//实例化子类对象
             cat.name="mimi";
             Animal animal = new Animal();//实例化父类对象
             animal.eat();
        }
    }
    登录后复制

    这里就创建了猫这个类然后继承了Animal类。我们实例化猫和Animal这个对象就可以调用方法和属性。

    那何为向上转型呢???

    原本子类对象的引用引用子类的对象,现在让父类的引用引用子类对象这就是向上转型。

    Java面向对象之多态实例分析

    我们利用代码理解一下:

    Java面向对象之多态实例分析

    这就是向上转型,我们也可以利用animal这个父类引用 调用方法;

    Java面向对象之多态实例分析

    这时我们就会发现利用这个引用能够调用父类的方法和属性,但是不能够调用子类的方法和属性,那为什么呢??原因就是因为父类没有子类这个方法,所以不能调用。总结:向上转型的时候也就是父类引用引用子类对象,这个父类引用只能调用父类有的属性和方法,不能调用子类的。

    向上转型的三种形式

    第一种:直接赋值

    也就是我们上面的那种写法:

      Animal animal1 = new Cat();//父类对象的引用 引用子类对象--->向上转型
      Animal animal2 = new Dog();
    登录后复制

    第二种:作为方法参数:

    Java面向对象之多态实例分析

    第三种作为返回值:

    Java面向对象之多态实例分析

    我们回到刚才的打印结果是什么;

    Java面向对象之多态实例分析

    但如果我把父类的方法变成我要吃猫粮呢?那结果毫无意外就是mimi我要吃猫粮。

    但是这就会出现一个问题,如果我在创建一个狗类,然后在调用eat方法 难道狗也要吃猫粮么?这就会出现问题,那我们可以在子类写一个eat方法;

    class Animal{
        public String name;//名字
        public int age;
        public void eat() {
            System.out.println(this.name+"要吃饭!!!");
        }
    }
    class Dog extends Animal{
        public void dark() {
            System.out.println("汪汪汪!!!");
        }
        public void eat() {
            System.out.println(this.name+"吃狗粮!!!");
        }
    }
    class Cat extends Animal{
        public void mew() {
            System.out.println("喵喵喵!!!");
        }
        public void eat() {
            System.out.println(this.name+"吃猫粮!!!");
        }
    }
    public class TestDemo1 {
        public static void main(String[] args) {
            //语法形式 : 父类 变量 = new 子类();
            Animal animal1 = new Cat();//父类对象的引用 引用子类对象--->向上转型
            Animal animal2 = new Dog();//父类对象的引用 引用子类对象--->向上转型
            animal1.name = "小猫";//访问父类属性
            animal2.name = "小狗";//访问父类属性
            animal1.eat();
            animal2.eat();
            // animal.mew();//访问子类特有的方法
        }
    }
    登录后复制

    这时又创建了一个狗类,然后又分别在两个子类创建两个eat方法。

    Java面向对象之多态实例分析

    我们发现这时候就变得很清楚就达到我们想要的效果了。

    但我们又应该想一想,为什么调用子类的eat方法而不调用父类的?

    动态绑定和静态绑定

    此时其实发生了动态绑定,我们可以看一下字节码文件,打开powershell窗口

    Java面向对象之多态实例分析

    我们都知道执行一个程序是先编译后运行,而这个是在编译的时候调用的是Animal的eat方法,而在运行的时候是调用的是Cat的方法这就是我们所说的运行时绑定或者可以说是动态绑定。

    那既然有动态绑定那肯定也有静态绑定。

    动态绑定是在编译的时候调用一个方法,而在运行时才是最后要确定调用的方法,也就是在运行时确定要调用那个方法。

    静态绑定就是在编译期间已经确定要调用哪个方法。

    其中,动态绑定最显著的代表就是方法重写。

    静态绑定最显著的代表就是方法重载。

    我们在回过头看上面的方法 ε=(´ο`*)))......怎么前面的eat方法返回值,参数列表,方法名都是一样的呢?我们来看一下。

    Java面向对象之多态实例分析

    方法的重写

    我们之前学过方法重载这里回顾一下方法重载,方法重载是方法名相同,返回值不做要求,参数列表不同。而我们今天学的方法重写是返回值相同,方法名称相同,参数列表相同,说是叫方法重写其实也可以叫做方法覆盖。

    方法重写有几点注意要求:

    方法重写满足 方法名相同,方法的参数列表相同,方法的返回值相同。

    Java面向对象之多态实例分析

    我们也可以一键生成重写

    Java面向对象之多态实例分析

    有几个注意事项:

    Java面向对象之多态实例分析

    不能重写被private修饰的方法。

    Java面向对象之多态实例分析

    不能重写被final修饰的方法。

    Java面向对象之多态实例分析

    子类的方法的访问权限一定要大于等于父类的访问权限。

    Java面向对象之多态实例分析

    重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成eat), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写.

    Java面向对象之多态实例分析

    被static修饰的方法也不能被重写

    总结方法重写的注意事项:

    • 被private,final修饰的方法不能被重写。

    • 被staitc修饰的方法也不能被重写。

    • @override 可以检查你重写的方法名是否正确,最好要加上。

    • 方法重写一定满足方法名相同,参数列表相同,返回值相同。

    对比方法重写与方法重载:

    Java面向对象之多态实例分析

    最后:重写不是进行在原来基础的修改,而是在原来基础上进行迭代和更新。

    进一步认识和理解多态

    场景:画一个图形

    class Shape{//创建一个图形类---->作为多种图形的父类
        public int length;//图形的长
        public int wide;//图形的宽
        public int height;//图形的高
        public void draw() {
            System.out.println("我要画一个图形!!!");
        }
    }
    class rectangle extends Shape{//长方形
        @Override
        public void draw() {
            System.out.println("我要画一个长方形!!!");
        }
    }
    class square extends Shape{
        @Override
        public void draw() {
            System.out.println("我要画一个正方形!!!");
        }
    }
    class circular extends Shape{
        @Override
        public void draw() {
            System.out.println("我要画一个圆形!!!");
        }
    }
    public class TestDemo1 {
        public static void method(Shape shape) {
            shape.draw();
        }
        public static void main(String[] args) {
            Shape shape1 = new circular();
            Shape shape2 = new rectangle();
            Shape shape3 = new square();
            method(shape1);
            method(shape2);
            method(shape3);
        }
    }
    登录后复制

    创建一个Shape(父类),然后创建三个子类分别是square ,circular,rectangle,利用父类引用这三个子类,接着调用method方法。

    Java面向对象之多态实例分析

    这就是多态,不同的对象,调用同一个方法最后结果产生出不同的状态。

    我们再来总结多态产生的条件:

    • 要在继承体系下

    • 子类要对父类的方法进行重写

    • 通过父类的引用调用重写的方法 

    也就是 在继承体系下  进行向上转型  和 方法重写

    多态的优点

    优点:

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

    • 如果使用多态, 则不必写这么多的 if - else 分支语句, 代码更简单.

    • 可扩展能力更强

    缺点:

    • 代码的运行效率降低

    还有一个重要点就是不要在构造方法中调用重写方法

    以上是Java面向对象之多态实例分析的详细内容。更多信息请关注PHP中文网其他相关文章!

    本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳图形设置
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您听不到任何人,如何修复音频
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解锁Myrise中的所有内容
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌

    热工具

    记事本++7.3.1

    记事本++7.3.1

    好用且免费的代码编辑器

    SublimeText3汉化版

    SublimeText3汉化版

    中文版,非常好用

    禅工作室 13.0.1

    禅工作室 13.0.1

    功能强大的PHP集成开发环境

    Dreamweaver CS6

    Dreamweaver CS6

    视觉化网页开发工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神级代码编辑软件(SublimeText3)

    Java 中的平方根 Java 中的平方根 Aug 30, 2024 pm 04:26 PM

    Java 中的平方根指南。下面我们分别通过例子和代码实现来讨论平方根在Java中的工作原理。

    Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

    Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

    Java 中的随机数生成器 Java 中的随机数生成器 Aug 30, 2024 pm 04:27 PM

    Java 随机数生成器指南。在这里,我们通过示例讨论 Java 中的函数,并通过示例讨论两个不同的生成器。

    Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

    Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

    Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

    Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

    Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

    在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

    突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

    Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

    Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

    Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

    See all articles