iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java多态的全面系统解析
  • 455
分享到

Java多态的全面系统解析

2024-04-02 19:04:59 455人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录Java基础知识(多态)多态多态的定义和存在的必要条件多态的定义:多态存在的三个必要条件多态的案例多态的好处多态的弊端引用类型转换1. 引用类型转换是什么,为什么需要它?2. 向

茫茫人海千千万万,感谢这一秒你看到这里。希望我的能对你的有所帮助!共勉!

愿你在未来的日子,保持热爱,奔赴山海!

Java基础知识(多态)

多态

因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

多态的定义和存在的必要条件

多态的定义:

  • 多态是指同一个行为具有多个不同表现形式或形态的能力。
  • 多态就是同一个接口,使用不同的实例而执行不同操作。

就举动物类的例子吧,cat和dog都是属于动物这一类,而动物呢,都有一个共同的行为就是吃?吧,而不同的动物所吃的食物都大不相同吧!

呢,它喜欢吃鱼

而对于狗呢,它就比较喜欢啃骨头

所以多态就是对于吃这一行为来说,每种动物对吃这一行为所表现的行为都不尽相同。

多态存在的三个必要条件

  • 继承或者实现

在多态中必须存在有继承或者实现关系的子类和父类。

  • 方法的重写

子类对父类中某些方法进行重新定义(重写),在调用这些方法时就会调用子类的方法。

  • 基类引用指向派生类对象,即父类引用指向子类对象

父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

✍多态的格式:

父类类型 变量名 = new 子类类型();

变量名.方法名();

多态格式可以充分体现了同一个接口,使用不同的实例而执行不同操作。

接下来我们具体来进行案例体会体会吧!???

多态的案例

多态我们首先要知道的一点:

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。如果子类没有重写该方法,就会调用父类的该方法。

总结起来就是:编译看左边?,运行看右边。?

首先我们先定义一个父类动物类,动物有吃的行为!

接着定义一个猫类和狗类去继承动物类,重写里面的吃行为!

☘️具体代码如下:

定义动物父类:


package com.nz.pojo;


public class Animal {

    public void eat() {
        System.out.println("动物它们都会吃东西!!!");
    }
}

定义猫咪子类:


package com.nz.pojo;


public class Cat extends Animal{

    public void eat() {
        System.out.println("小喵咪都喜欢吃鱼罐头!");
    }
}

定义小狗子类:


package com.nz.pojo;


public class Dog extends Animal{

    public void eat() {
        System.out.println("小狗狗都爱啃骨头!");
    }
}

定义测试类,测试多态的形式:


package com.nz;

import com.nz.pojo.Animal;
import com.nz.pojo.Cat;
import com.nz.pojo.Dog;


public class Demo {
    public static void main(String[] args) {

        // 多态形式,创建猫类对象
        Animal animal = new Cat();
        // 调用的是Cat的 eat
        animal.eat();

        // 多态形式,创建狗类对象
        Animal animal2 = new Dog();
        // 调用的是Dog的eat
        animal2.eat();
    }
}

得到的结果:

小喵咪都喜欢吃鱼罐头!
小狗狗都爱啃骨头!

类的大致结构:

可以看出我们可以使用多态的属性得到不同的动物的一个吃的行为属性!

多态的好处

提高了代码的拓展性,使用父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用。

具体我们来看看吧:

继续使用上述的动物类、猫类、狗类吧。

定义测试类:


package com.nz;

import com.nz.pojo.Animal;
import com.nz.pojo.Cat;
import com.nz.pojo.Dog;


public class Demo2 {
    public static void main(String[] args) {
        // 创建猫和狗对象
        Cat cat = new Cat();
        Dog dog = new Dog();

        // 调用catEat
        catEat(cat);
        // 调用dogEat
        dogEat(dog);

		
        animalEat(cat);
        animalEat(dog);
    }

    
    public static void catEat (Cat cat){
        cat.eat();
    }

    public static void dogEat (Dog dog){
        dog.eat();
    }

    public static void animalEat (Animal animal){
        animal.eat();
    }
}

执行结果:

小喵咪都喜欢吃鱼罐头!
小狗狗都爱啃骨头!
小喵咪都喜欢吃鱼罐头!
小狗狗都爱啃骨头!

可以看出,由于多态的特性,我们的animalEat()方法传入的Animal类型参数,并且它是我们的Cat和Dog的父类类型,父类类型接收子类对象,所以我们可以将Cat对象和Dog对象,传递给animalEat()方法。

所以我们可以完全使用animalEat()方法来替代catEat()方法和dogEat()方法,达到同样的效果!以至于我们可以不必再单独写xxxEat()方法来传入指定的动物参数了,从而实现了实现类的自动切换。

所以多态的好处体现在:可以使我们的程序编写的更简单,并有良好的扩展性。

多态的弊端

从上面的多态的好处,可以看到我们可以使用父类的参数代替了某个子类的参数,从而达到程序的扩展!

但是对于某个子类有些独有的功能方法时,此时我们的多态的写法就无法访问子类独有功能了。

具体来瞧瞧?

代码如下:

重新定义下猫的子类:


package com.nz.pojo;


public class Cat extends Animal{

    public void eat() {
        System.out.println("小喵咪都喜欢吃鱼罐头!");
    }

    
    public void playBall() {
        System.out.println("小喵咪都喜欢小球!");
    }
}

定义测试类:


package com.nz;

import com.nz.pojo.Animal;
import com.nz.pojo.Cat;


public class Demo3 {
    public static void main(String[] args) {
        Animal animal = new Cat();

        animal.eat();

        animal.playBall();//编译报错,编译看左边,Animal没有这个方法
    }
}

可以看到动物类和猫类有个共同的eat吃方法,但是呢,猫咪多了个玩球球的方法。而对于动物对象来说,它本身动物类没有玩球球的方法,所以它的编译就直接没有通过了!

那有什么方法解决呢?且看下一章节吧!

引用类型转换

1. 引用类型转换是什么,为什么需要它?

从上面的多态的弊端的案例中,我们可以看到,我们使用动物对象时无法直接访问到猫类中的玩球球方法,这也就是我们之前说的编译看左边,运行看右边。

而在我们使用多态方式调用方法时,首先检查会左边的父类中是否有该方法,如果没有,则编译错误。也就代表着,父类无法调用子类独有的方法。、

所以说,如果编译都错误,更别说运行了。这也是多态给我们带来的一点小困扰,而我们如果想要调用子类特有的方法,必须做向下转型。

2. 向上转型(自动转换)

对于向下转型,我们先来讲解下向上转型的概念吧。

向上转型:

多态本身是子类向父类向上转换(自动转换)的过程,这个过程是默认的。当父类引用指向一个子类对象时,便是向上转型。

对于父类和子类的关系来说,具体来看图说话:

父类相对与子类来说是大范围的类型,Animal是动物类,是父类。而Cat是猫咪类,是子类。

所以对于父类Animal来说,它的范围是比较大的,它包含一切动物,包括猫咪类和小狗类。

所以对于子类类型这种范围小的,我们可以直接自动转型给父类类型的变量。

使用格式:

父类类型 变量名 = new 子类类型();

如:Animal animal = new Cat();

相当于有:
Animal animal = (Animal) new Cat();

相当于自动帮我们了一个隐形的转换为动物类的一个过程,因为动物本身就包含了猫咪。

3. 向下转型(强制转换)

向上转型可以知道它是子类自动转换为父类的一个过程,所以我们现在再来看看向下转型的定义:

向下转型:

向下转型就是由父类向子类向下转换的过程,这个过程是强制的。一个需要将父类对象转为子类对象,可以使用强制类型转换的格式,这便是向下转型。

为什么这种就必须自己强制加上一个类型转换过程呢?

对于父类和子类的关系来说,我们接着看图说话:

对于猫咪类的话,它在动物类中只是其中的一部分吧,而对于动物类来说,它有许多其他子类动物如狗,牛,猪等等。

所以对于动物父类想要向下转型的时候, 它此时不知道指向那个子类,因为不确定呀,所以就必须自己加上强制的类型转换的一个过程。

使用格式:

子类类型 变量名 = (子类类型) 父类变量名;
如:
Animal animal = new Cat();
Cat cat = (Cat) animal;
cat.playBall();// 此时我们就可以使用猫咪的特有方法啦

所以对于多态的弊端,无法使用子类特有的参数,我们也解决啦,可以通过向下转型的方法,从而将类型强制转换为某个子类对象后,再去调用子类的特有方法!

4. 向下转型的问题

虽然我们可以使用向下转型使得我们可以使用子类的独有方法,但是转型的过程中,一不小心就会遇到这样的问题了,来,我们来看看下面的代码:


public class Test {
    public static void main(String[] args) {
        // 向上转型  
        Animal a = new Cat();  
        a.eat();               // 调用的是 Cat 的 eat

        // 向下转型  
        Dog d = (Dog)a;       
        d.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】
    }  
}

这段代码可以通过编译,但是运行时,却报出了 ClassCastException ,类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。

5. 转型的异常

转型的过程中,一不小心就会遇到这样的问题,请看如下代码:

定义狗类中额外的独有遛狗方法:


package com.nz.pojo;


public class Dog extends Animal{

    public void eat() {
        System.out.println("小狗狗都爱啃骨头!");
    }

    public void walk() {
        System.out.println("小狗在被我溜着!");
    }
}

定义测试类


package com.nz;

import com.nz.pojo.Animal;
import com.nz.pojo.Cat;
import com.nz.pojo.Dog;


public class Demo4 {
    public static void main(String[] args) {

        // 向上转型的过程
        Animal animal = new Cat();

        // 调用了猫咪的吃方法
        animal.eat();

        // 向下转型
        Dog dog = (Dog) animal;

        dog.walk(); // 调用的是 Dog 的 walk 可以通过,但是会运行报错
    }
}

得到结果:

小喵咪都喜欢吃鱼罐头!
Exception in thread "main" java.lang.ClassCastException: com.nz.pojo.Cat cannot be cast to com.nz.pojo.Dog
at com.nz.Demo4.main(Demo4.java:20)

我们可以看到,虽然我们的代码通过编译,但是终究在运行时,还是出错了,抛出了 ClassCastException 类型转换的异常。

其实我们可以知道,我们在上面的时候,创建了Cat类型对象,而在向下转型时,将其强行转换为了Dog类型,所以程序在运行时,就会抛出类型转换的异常!

那我们如何可以避免这种异常发生呢?且看下一节分析!

6. instanceof关键字

Java为我们提供一个关键字instanceof ,它可以帮助我们避免了ClassCastException 类型转换异常的发生。

那如何做呢?

格式:

变量名 instanceof 数据类型

解释:

  • 如果变量属于该数据类型或者其子类类型,返回true。
  • 如果变量不属于该数据类型或者其子类类型,返回false。

代码实现:


package com.nz;

import com.nz.pojo.Animal;
import com.nz.pojo.Cat;
import com.nz.pojo.Dog;


public class Demo5 {
    public static void main(String[] args) {

        // 向上转型的过程
        Animal animal = new Cat();

        // 调用了猫咪的吃方法
        animal.eat();

        // 向下转型
        if (animal instanceof Cat){
            Cat cat = (Cat) animal;
            cat.playBall();        // 调用的是 Cat 的 playBall
        } else if (animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.walk();       // 调用的是 Dog 的 walk
        }
    }
}

结果:

小喵咪都喜欢吃鱼罐头!
小喵咪都喜欢小球!

可以发现,它可以帮助我们在做类型转换前,判断该类型是否属于该类型或者子类类型,如果是,我们就可以强转啦!

总结

相信各位看官都对Java中的特性之一多态的知识和使用有了一定了解,等待下一次更多Java基础的学习吧!

让我们也一起加油吧!本人不才,如有什么缺漏、错误的地方,也欢迎各位人才大佬评论中批评指正!

学到这里,今天的世界打烊了,晚安!虽然这篇文章完结了,但是我还在,永不完结。我会努力保持写文章。来日方长,何惧车遥马慢!

感谢各位看到这里!愿你韶华不负,青春无悔!

到此这篇关于Java多态的全面系统解析的文章就介绍到这了,更多相关Java 多态内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java多态的全面系统解析

本文链接: https://www.lsjlt.com/news/141100.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java多态的全面系统解析
    目录Java基础知识(多态)多态多态的定义和存在的必要条件多态的定义:多态存在的三个必要条件多态的案例多态的好处多态的弊端引用类型转换1. 引用类型转换是什么,为什么需要它?2. 向...
    99+
    2024-04-02
  • Java全面分析面向对象之多态
    目录多态的理解向上转型向上转型的三种形式动态绑定和静态绑定方法的重写进一步认识和理解多态多态的优点多态的理解 什么是多态呢??从字面理解就是多种形态,也就是不同类实例化出来的对象调用...
    99+
    2024-04-02
  • Android4.2系统全面解析
    Android 4.2是一个由Google开发的移动操作系统。它是Android操作系统的第四个主要版本,于2012年11月发布。以...
    99+
    2023-09-25
    Android
  • C++多态的全面讲解
    目录1.多态的定义和实现多态的浅层理解多态的构成条件2.虚函数虚函数的重写规则虚函数重写条件的两个例外1.协变(返回值不同)2.析构函数的重写(函数名不同)3.C++11 overr...
    99+
    2024-04-02
  • 全面解析CRM管理系统
    CRM管理系统,即客户关系管理系统,是一种用于管理与客户交互的软件工具。它可以帮助企业更好地了解和管理客户,提高客户满意度,从而提高销售和利润。本篇文章将详细介绍CRM管理系统的工作原理、特点、应用领域以及如何选择和实施CRM系统。 工作原...
    99+
    2023-11-23
    管理系统 CRM
  • Java CGLib动态代理机制(全面解析)
    一、首先说一下JDK中的动态代理:JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编...
    99+
    2023-05-31
    java 动态代理 cglib
  • C++超全面讲解多态
    目录多态的概念多态的定义及实现构成条件虚函数虚函数的重写虚函数重写的两个例外抽象类抽象类的概念接口继承和实现继承多态的原理虚函数表多态的原理多态的概念 概念:通俗的来说就是多种形态,...
    99+
    2024-04-02
  • java注解的全面分析
    全面解析java注解Java中的常见注解 a.JDK中的注解    @Override 覆盖父类或者父接口的方法    @Deprecated 表示方法已经过时 &nbs...
    99+
    2023-05-31
    java 注解 ava
  • Java面试高频问题之RabbitMQ系列全面解析
    1.RabbitMQ是什么? RabbitMQ是一款开源的,Erlang编写的,基于AMQP(高级消息队列协议)协议的消息中间件。 2.为什么要使用消息队列? 从本质上来说是因为互联...
    99+
    2024-04-02
  • Java面向对象之多态的示例分析
    这篇文章主要介绍Java面向对象之多态的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!public class Polymorphism {public static&...
    99+
    2023-06-02
  • 全面解析Android系统指纹启动流程
    本章主要整理Android 指纹启动流程,侧重于hal和framework部分。 一.从Android系统启动流程看指纹启动流程 下图图片出处  → 第一阶段 ...
    99+
    2024-04-02
  • Java多层嵌套JSON类型数据全面解析
    目录多层嵌套JSON类型数据解析以下举例数据结构解析代码json解析多层嵌套并转为对应类(List)Json(随便扒的格式,将就看~)关键依赖JAVABEAN转JSONObject多...
    99+
    2024-04-02
  • Vista系统是什么意思?全面解析Windows Vista系统知识
      本文向大家相信介绍关于Vista系统的知识,包括Vista系统是什么意思,Windows Vista和Longhorn有什么关系,Windows Vista 最大的改变在哪些地方等等,文章介绍地非常详细,很不错,希望...
    99+
    2023-06-05
    Vista系统 Windows Vista 意思 系统 知识
  • Java面向对象之多态实例分析
    这篇文章主要介绍“Java面向对象之多态实例分析”,在日常操作中,相信很多人在Java面向对象之多态实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java面向对象之多态实例分析”的疑惑有所帮助!接下来...
    99+
    2023-06-30
  • java多态实现电子宠物系统
    本文实例为大家分享了java多态实现电子宠物系统的具体代码,供大家参考,具体内容如下 效果实现: 代码实现: 1、主人类: public class Master {     //...
    99+
    2024-04-02
  • Java全面系统介绍反射的运用
    目录反射反射定义反射的基本运用1.获取类对象a.forName()方法b.直接获取c.getClass()方法d.getSystemClassLoader().loadClass()...
    99+
    2024-04-02
  • Java之CountDownLatch原理全面解析
    目录CountDownLatch原理解析1. demo展示2. 原理解析Java CountDownLatch学习总结来源包业务书写示例一般代码示例CountDownLatch原理解...
    99+
    2022-11-13
    Java CountDownLatch CountDownLatch原理 CountDownLatch原理解析
  • 详细全面解析Java泛型
    1.概述 作为一个面向对象的编程语言,Java可以通过实现一些类,作为我们各种需求的一个模板,方便我们的使用。但有时候,这个类的范围可能比我们想要的范围要大,我们只想限定于满足类的某...
    99+
    2024-04-02
  • Java面向对象编程(封装/继承/多态)实例解析
    本文主要介绍了面向对象的三大特征实例解析,下面看看具体内容。封装封装一个Teacher和Student类package com.hz.test;public class Teacher { private String name; pr...
    99+
    2023-05-30
    java 面向对象 ava
  • Java线程安全状态专题解析
    一、观察线程的所有状态 线程的状态是一个枚举类型 Thread.State public static void main(String[] args) { f...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作