广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >【Java】Java中的多态
  • 201
分享到

【Java】Java中的多态

java开发语言 2023-09-05 20:09:36 201人浏览 泡泡鱼
摘要

文章目录 一、什么是多态二、多态实现的条件三、重写3.1 什么是重写3.2 重写和重载的区别 四、向上转型和向下转型4.1 向上转型4.2 向下转型 五、多态的优缺点六、避免在构造方法

文章目录


一、什么是多态

在Java中,多态是面向对象编程中的一个重要概念,它允许不同类型的对象对同一方法进行不同的实现。具体来说,多态性指的是通过父类的引用变量来引用子类的对象,从而实现对不同对象的统一操作

例如:狗和猫都是动物,动物共同的行为都有吃这个动作,而狗可以表现为啃骨头,猫则可以表现为吃老鼠。这就是多态的表现,即同一件事情,发生在不同对象的身上,就会产生不同的结果。

二、多态实现的条件

在Java中,要实现多态性,就必须满足以下条件:

  1. 继承关系
    存在继承关系的类之间才能够使用多态性。多态性通常通过一个父类用变量引用子类对象来实现。

  2. 方法重写
    子类必须重写(Override)父类的方法。通过在子类中重新定义和实现父类的方法,可以根据子类的特点行为改变这个方法的行为,如猫和狗吃东西的独特行为。

  3. 父类引用指向子类对象
    使用父类的引用变量来引用子类对象。这样可以实现对不同类型的对象的统一操作,而具体调用哪个子类的方法会在运行时多态决定

例如,下面的案例是根据猫和狗叫的动作的不同,而实现的多态:

class Animal {    public void sound() {        System.out.println("动物发出声音");    }}class Dog extends Animal {    @Override    public void sound() {        System.out.println("狗发出汪汪声");    }}class Cat extends Animal {    @Override    public void sound() {        System.out.println("猫发出喵喵声");    }}public class Main {    public static void main(String[] args) {        Animal animal1 = new Dog(); // 父类引用指向子类对象        Animal animal2 = new Cat(); // 父类引用指向子类对象        animal1.sound(); // 输出:狗发出汪汪声        animal2.sound(); // 输出:猫发出喵喵声    }}

在这个示例中,Animal 类是父类,DogCat 类是它的子类。通过将父类的引用变量分别指向子类对象,实现了多态性。在运行时,根据引用变量的实际类型来调用相应的子类方法,从而输出不同的声音。

三、重写

3.1 什么是重写

在面向对象编程中,重写(Override)指的是子类重新定义和实现了从父类继承而来的方法,以改变方法的行为。子类通过重写方法可以提供自己特定的实现,使得父类方法的行为在子类对象的身上有不同的表现。

想要理解方法重写,需要知道以下概念:

  1. 继承关系
    重写方法是基于父类和子类之间的继承关系。子类继承了父类的方法,包括方法的名称、参数列表和返回类型。

  2. 方法签名
    重写的方法与父类的方法具有相同的方法签名,即方法的名称、参数列表和返回类型必须一致(当然,如果返回类型的对象本身的类型则可以不同,但是必须要有继承关系)。方法签名不包括方法体。

  3. @Override注解
    为了明确表明这是一个重写的方法,可以使用 @Override 注解来标记子类中的方法。该注解会在编译时检查是否满足重写条件,如果不满足会报错。

  4. 动态绑定
    通过父类引用变量调用被子类重写的方法时,会根据实际引用的对象类型,在运行时动态绑定到相应的子类方法。

方法重写的规则:

  1. 方法名称、参数列表和返回类型必须与父类中被重写的方法相同。

  2. 子类重写的方法的访问修饰符的权限不能低于父类中被重写方法的访问修饰符权限。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected

  3. 重写的方法不能抛出比父类中被重写的方法更多或更宽泛的异常。子类中重写的方法可以抛出相同的异常或更具体的异常,或者不抛出异常。

    • 例如,如果父类的方法声明抛出 ioException,则子类中重写的方法可以抛出 IOExceptionFileNotFoundException,或者不抛出异常,但不能抛出比 IOException 更通用的异常,如 Exception
  4. 重写的方法必须具有相同的方法体,或者可以进行方法体的扩展。

    • 子类中重写的方法可以调用父类中被重写的方法,使用 super 关键字。

3.2 重写和重载的区别

首先回顾重载的实现条件:

  1. 方法名称相同:重载的方法必须具有相同的名称。
  2. 参数列表不同:重载的方法的参数列表必须不同。参数列表可以通过参数的类型、个数或顺序的不同来区分重载方法
  3. 返回类型可以相同也可以不同:重载的方法可以具有相同的返回类型,也可以具有不同的返回类型。返回类型不是重载方法的区分标准。
  4. 方法所在的类中:重载方法必须定义在同一个类中
  5. 方法的访问修饰符和异常:重载方法可以具有相同的访问修饰符(如 publicprivateprotected)和抛出的异常。

重写和重载的区别:

重写(Override)和重载(Overload)是Java中两个不同的概念,它们在方法的处理方式和实现上有所不同。

  • 重载(Overload)指的是在同一个类中,根据方法的参数列表的不同,定义多个具有相同名称但参数类型或个数不同的方法。重载的方法具有相同的名称,但方法签名不同。

  • 重写(Override)指的是子类重新定义和实现了从父类中继承的方法。重写的方法具有与父类方法相同的名称、参数列表和返回类型。

下面是重写和重载的区别:

  1. 定义位置:重载方法定义在同一个类中,而重写方法定义在父类和子类之间。

  2. 方法签名:重载方法具有相同的名称,但方法签名(参数类型和个数)不同。重写方法具有相同的名称和方法签名。

  3. 继承关系:重载方法不涉及继承关系,可以在同一个类中定义。重写方法是在子类中对父类方法的重新定义和实现。

  4. 运行时调用:重载方法是根据方法的参数列表的不同进行静态绑定,在编译时确定。重写方法是根据对象的实际类型进行动态绑定,在运行时确定。

  5. 目的:重载方法用于在同一个类中实现相似功能但具有不同参数的方法。重写方法用于子类重新定义父类方法的行为,以适应子类的特定需求。

总结来说,重载是在同一个类中根据参数列表的不同定义多个具有相同名称但参数不同的方法,而重写是子类重新定义和实现了从父类继承的方法重载方法通过静态绑定在编译时确定调用,重写方法通过动态绑定在运行时确定调用重载用于实现相似功能但具有不同参数的方法,重写用于改变父类方法的行为以适应子类的需求

四、向上转型和向下转型

4.1 向上转型

向上转型(Upcasting)是指将一个子类的对象引用赋值给其父类类型的引用变量。这是在面向对象编程中的一种常见操作,用于实现多态性和灵活的对象处理。

在向上转型中,子类对象可以被视为父类对象,可以使用父类类型的引用变量来引用子类对象。这样做的好处是可以以统一的方式处理不同类型的对象,实现代码的灵活性和可扩展性。

向上转型的特点和规则如下:

  1. 子类对象可以隐式地转型为父类对象,不需要任何显式的类型转换操作。

  2. 父类引用变量可以引用子类对象,但通过父类引用变量只能访问到子类对象中定义的父类成员,无法访问子类独有的成员。

  3. 子类对象中重写的方法,在通过父类引用变量调用时,会调用子类中的实现(动态绑定)。

  4. 向上转型是安全的操作,因为子类对象本身就是一个父类对象。

下面是一个简单的示例代码,展示了向上转型的使用:

class Animal {    public void eat() {        System.out.println("Animal is eating.");    }}class Dog extends Animal {    @Override    public void eat() {        System.out.println("Dog is eating.");    }    public void bark() {        System.out.println("Dog is barking.");    }}public class Main {    public static void main(String[] args) {        Animal animal = new Dog();  // 向上转型        animal.eat();  // 调用的是 Dog 类中的 eat() 方法        // animal.bark();  // 错误:无法访问 Dog 类中独有的方法        Dog dog = (Dog) animal;  // 向下转型        dog.bark();  // 调用 Dog 类中的 bark() 方法    }}

在上述示例中,存在一个继承关系:类 Dog 继承自类 Animal。在 Main 类的 main 方法中,首先创建了一个 Dog 类的对象,并将其赋值给一个 Animal 类型的引用变量 animal,这就是向上转型的过程。通过 animal 引用变量,可以调用 eat() 方法,而在运行时,实际执行的是 Dog 类中重写的 eat() 方法。

需要注意的是,虽然 animal 引用变量的类型是 Animal,但是它指向的是一个 Dog 类的对象,因此可以将其重新转型为 Dog 类型(向下转型),并通过 dog 引用变量访问 Dog 类中独有的成员方法 bark()

总结起来,向上转型允许将子类对象视为父类对象,以父类类型的引用变量来引用子类对象,实现多态性和灵活的对象处理。

4.2 向下转型

向下转型(Downcasting)是指将一个父类类型的引用变量转换为其子类类型的引用变量。它与向上转型相反,需要进行显式的类型转换操作。

在某些情况下,当一个对象被向上转型后,它的具体类型信息会丢失,只保留了父类类型的信息。如果我们需要访问子类中特有的成员或调用子类重写的方法,就需要使用向下转型。

需要注意的是,向下转型是有风险的,因为转换的对象必须是实际上是子类对象才能成功,否则会在运行时抛出 ClassCastException 异常。

下面是一个示例代码,展示了向下转型的使用:

class Animal {    public void eat() {        System.out.println("Animal is eating.");    }}class Dog extends Animal {    @Override    public void eat() {        System.out.println("Dog is eating.");    }    public void bark() {        System.out.println("Dog is barking.");    }}public class Main {    public static void main(String[] args) {        Animal animal = new Dog();  // 向上转型        // 使用向下转型之前,需要先检查对象是否实际上是子类的实例        if (animal instanceof Dog) {            Dog dog = (Dog) animal;  // 向下转型            dog.bark();  // 调用 Dog 类中的 bark() 方法        } else {            System.out.println("animal is not an instance of Dog");        }    }}

在上述示例中,首先创建了一个 Dog 类的对象,并将其赋值给一个 Animal 类型的引用变量 animal,这就是向上转型的过程。然后,通过使用 instanceof 运算符检查 animal 是否是 Dog 类的实例,以确保进行向下转型时的类型安全。

如果 animalDog 类的实例,那么可以将其转型为 Dog 类型,并使用 dog 引用变量调用 Dog 类中特有的方法 bark()。如果 animal 不是 Dog 类的实例,则可以根据实际需求进行相应的处理。

需要注意的是,在进行向下转型之前,一定要确保对象实际上是子类的实例,否则会导致 ClassCastException 异常。因此,在进行向下转型之前,应该使用 instanceof 运算符进行类型检查,以避免出现异常情况。

五、多态的优缺点

Java多态性的优点:

  1. 灵活性和可扩展性:多态性使得代码具有更高的灵活性和可扩展性。通过使用父类类型的引用变量,可以以统一的方式处理不同类型的对象,无需针对每个具体的子类编写特定的代码。

  2. 代码复用:多态性可以促进代码的复用。可以将通用的操作定义在父类中,然后由子类继承并重写这些操作。这样一来,多个子类可以共享相同的代码逻辑,减少了重复编写代码的工作量。

  3. 可替换性:多态性允许将一个对象替换为其子类的对象,而不会影响程序的其他部分。这种可替换性使得系统更加灵活和可维护,可以方便地添加新的子类或修改现有的子类,而无需修改使用父类的代码。

  4. 代码扩展性:通过引入新的子类,可以扩展现有的代码功能,而无需修改现有的代码。这种可扩展性使得系统在需求变化时更加容易适应和扩展。

Java多态性的缺点:

  1. 运行时性能损失:多态性需要在运行时进行方法的动态绑定,这会带来一定的性能损失。相比于直接调用具体的子类方法,多态性需要在运行时确定要调用的方法,导致额外的开销。

  2. 代码可读性下降:多态性使得代码的行为变得更加动态和不确定。在某些情况下,可能需要跟踪代码中使用的对象类型和具体的方法实现,这可能降低代码的可读性和理解性。

  3. 限制访问子类特有成员:通过父类类型的引用变量,只能访问父类及其继承的成员,无法直接访问子类特有的成员。如果需要访问子类特有的成员,就需要进行向下转型操作,这增加了代码的复杂性和维护的难度。

虽然多态性具有一些缺点,但在大多数情况下,其优点远远超过缺点,使得代码更具灵活性、可扩展性和可维护性。因此,多态性在Java编程中被广泛应用。

六、避免在构造方法中调用重写的方法

先来看一段代码:

class B {    public B() {        // do nothing        func();    }    public void func() {        System.out.println("B.func()");    }}class D extends B {    private int num = 1;    @Override    public void func() {        System.out.println("D.func() " + num);    }}public class Test {    public static void main(String[] args) {        D d = new D();    }}

上面这段代码的运行结果是:D.func 0,其原因如下:

  • 构造 D 对象的同时, 会调用 B 的构造方法。
  • B 的构造方法中调用了 func 方法, 此时会触发动态绑定, 会调用到 D 中的 func 方法。
  • 此时 D 对象自身还没有构造,因此 num 处在未初始化的状态,其值为 0。 如果具备多态性,num的值则应该是1。
  • 所以在构造函数内,尽量避免使用实例方法,除了 finalprivate 方法。

通过上面的例子告诉我们一个道理,那就是:“用尽量简单的方式使对象进入可工作状态”,尽量不要在构造器中调用方法(如果这个方法被子类重写,就会触发动态绑定,但是此时子类对象还没构造完成),可能会出现一些隐藏的但是又极难发现的问题。

来源地址:https://blog.csdn.net/qq_61635026/article/details/131245120

--结束END--

本文标题: 【Java】Java中的多态

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

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

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

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

下载Word文档
猜你喜欢
  • 【Java】Java中的多态
    文章目录 一、什么是多态二、多态实现的条件三、重写3.1 什么是重写3.2 重写和重载的区别 四、向上转型和向下转型4.1 向上转型4.2 向下转型 五、多态的优缺点六、避免在构造方法...
    99+
    2023-09-05
    java 开发语言
  • Java中的多态
    一、多态定义及存在条件 1.1 多态的定义 多态是什么? 多态是同一个行为具有不同的表现形式或形态的能力同一方法可以根据发送对象的不同而采用不同的行为方式 例如:打印机分为黑白打印机和彩色打印机,在黑白打印机情况下打出来为黑白,在彩色打印机...
    99+
    2023-08-31
    java
  • 【JAVA】多态
    作者主页:paper jie_的博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将ja...
    99+
    2023-09-06
    java 开发语言
  • Java-多态
    目录 1.多态的概念 2.多态的实现条件。 3.重写 4.向上转型和向下转型 5.多态的优缺点 6.避免在构造方法中调用重写方法 1.多态的概念         多态字面意思就是多种形态,具体点就是完成某个行为时,不同的对象完成时产生...
    99+
    2023-08-31
    java 开发语言
  • Java之多态
    多态 多态的实现条件重写重写的定义重写的例子方法重写的条件 多态思想动态绑定与静态绑定 作者简介: zoro-1,目前大一,正在学习Java,数据结构等 作者主页:zoro-1的主页 欢迎大家点赞 👍...
    99+
    2023-08-16
    java 开发语言 笔记
  • 类的多态性(JAVA)
    目录 多态  重写  向上转型 类的多态性例子:  多态的优缺点   多态  所有的OOP语言都会有三个特征: 封装(点击可跳转)继承(点击可跳转)多态 多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。 在ja...
    99+
    2023-09-01
    开发语言 java
  • 怎样理解Java中的多态
    今天就跟大家聊聊有关怎样理解Java中的多态,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、多态的概念       继承关系使一个子类能继承...
    99+
    2023-06-22
  • Java中接口的多态详解
    目录多态参数多态数组接口的多态传递现象总结多态参数 就像我们现实生活中电脑的usb接口,我们既可以接受手机对象,又可以接受相机对象,等等,体现了接口的多态,查看以下代码 接口: pa...
    99+
    2022-11-13
  • Java多态详解
    目录 1. 基本介绍1.1 多态的概念1.2 多态的具体体现1.3 入门案例 2. 多态的转型2.1 向上转型2.2 向下转型2.3 代码示例2.4 转型的异常2.4.1 类型转换异常2....
    99+
    2023-10-03
    java
  • Java编程 多态
    目录一、向上转型二、转机1、绑定2、扩展性3、缺陷三、构造器与多态1、构造器的调用顺序2、构造器内部的多态方法的行为四、协变返回类型五、继承进行设计前言: 封装,是合并属性和行为创建...
    99+
    2022-11-12
  • Java中怎么实现多态
    这篇文章将为大家详细讲解有关Java中怎么实现多态,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。多态多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确...
    99+
    2023-06-20
  • Java中多态的用法有哪些
    这期内容当中小编将会给大家带来有关Java中多态的用法有哪些,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。多态性是通过:1 接口和实现接口并覆盖接口中同一方法的几不同的类体现的2 父类和继承父类并覆盖父类...
    99+
    2023-05-31
    java ava
  • Java中多态的优势是什么
    Java中多态的优势是什么?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.向上转型。之前继承有提到过。父类引用指向子类对象。这时的引用只能调用子类覆盖重写了的方法,不能调...
    99+
    2023-06-15
  • java中多态的原理是什么
    今天就跟大家聊聊有关java中多态的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;2...
    99+
    2023-06-14
  • java中的多态是如何实现的
    什么是多态面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。多态的定义指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)实现多态的技...
    99+
    2017-08-04
    java 多态 实现
  • java多态是什么
    多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作,如图所示: (推荐学习:java课程)多态性是对象多种表现形式的体现。现实中,比如我们按下 F1 键这个动作:如果当前在 Flash 界面...
    99+
    2015-05-12
    java入门 java
  • java 多态是什么
    多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:多态性是对象多种表现形式的体现。现实中,比如我们按下 F1 键这个动作: ·如果当前在 Flash 界面下弹出的就是 AS 3 的...
    99+
    2020-09-04
    java入门 java 多态
  • 如何在Java中实现多态
    小编给大家分享一下如何在Java中实现多态,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!public class Polymorphism5 {//打印人吃水果的信息public v...
    99+
    2023-06-02
  • java中多态原理的示例分析
    这篇文章将为大家详细讲解有关java中多态原理的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开发...
    99+
    2023-06-14
  • java多态中的就近原则介绍
    直接上题: 题目补充: class A { int m; //-10 int getM() { retu...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作