Java 中的重载(overload)和重写(override)

news2024/11/25 10:47:05

​         重载和重写都是面向对象编程中的概念,但我们或许还听说过一种叫做覆写(overwrite)的概念。C++ 是拥有这个概念的,Java 只有 overload 和 override,Python 只有隐式的 overload 和 override,没有 overwrite 的概念。在重载(overload)、重写(override)和覆写(overwrite)中,我们一般对前面两个比较熟悉,对最后一个会略微陌生一些。

重载(overload)

重载的定义及规则

重载是指在一个类中,可以定义多个方法名相同但参数类型、个数或顺序不同的方法。JVM 编译器会根据传入的参数自动匹配并调用对应的方法。

重载的目的是为了让程序员能够使用同一个方法名来处理多种不同类型的参数。通过方法重载,程序员可以根据实际需要创建多个具有相同名称但参数列表不同的方法,这些方法可以用于执行类似但不完全相同的操作。这样做可以使代码更加简洁、灵活和易于维护,同时也提高了代码的复用性。最典型的,System.out.println() 方法就是一个被重载过的方法,它可以接受各种不同类型的参数,并且输出它们对应的字符串表示形式。

重载必须满足下面的规则:

  • 参数列表必须改变;
  • 返回类型可以改变;
  • 实现过程可以改变;
  • 异常声明可以改变;
  • 访问限制可以改变;

总结:外壳必须改变,内核可以改变。

重载方法的参数列表不能相同是因为编译器需要根据调用时传递的实际参数类型来确定要调用哪个重载方法。如果两个重载方法的参数列表相同,则编译器无法区分它们,并且会导致编译错误。至于返回类型和实现过程等,这些部分并不会影响到 JVM 对重载方法的区分,自然也就没有任何要求,是否修改都是可以的。

下面是一个简单的重载示例:

public class Overload {
    public static void print(Integer a) {
        // 当传入参数的类型为Integer时,JVM会调用这个方法
        System.out.println("传入参数为Integer类型");
    }

    public static void print(String s) {
        // 当传入参数的类型为String时,JVM会调用这个方法
        System.out.println("传入参数为String类型");
    }

    public static void main(String[] args) {
        Overload.print(1); // Output:传入参数为Integer类型
        Overload.print("1"); // Output:传入参数为String类型
    }
}

但其实重载中 JVM 自动寻找并匹配参数列表的过程,我们可以在一定程度上手动模拟完成:

public class Overload {
    public static void print(Object o) {
        // 模拟 JVM 匹配参数列表的过程
        if (o instanceof Integer)
            System.out.println("传入参数为Integer类型");
        else if (o instanceof String)
            System.out.println("传入参数为String类型");
        else
            throw new Error("Unresolved compilation problem:");
    }

    public static void main(String[] args) {
        Overload.print(1); // Output:传入参数为Integer类型
        Overload.print("1"); // Output:传入参数为String类型
    }
}

其他编程语言中的重载

C++ 和 Java 在类的方法重载上面极其相似,不再详述。

Python 的重载就不太一样了,它是一门动态类型的语言,变量和参数没有确定的类型,自然没有真正的重载了。它的重载类似于上面手动模拟重载的过程,算是隐式的重载。在 Python 的内置库 typing 中有一个 overload 装饰器可以让 IDE 理解这是一个重载函数或者方法,但这并不是真正的重载,而是虚拟的。

from typing import overload


@overload
def fake_overload(x: int) -> None: ...  # 没有实现过程,实际被覆盖
@overload
def fake_overload(x: str) -> None: ...  # 没有实现过程,实际被覆盖


def fake_overload(x: int | str) -> None:  # 真正实现过程的部分
    """ 伪重载 """
    if type(x) == int:
        print('传入参数为int类型')
    elif type(x) == str:
        print('传入参数为str类型')
    else:
        raise TypeError

重写(override)

重写的定义及规则

重写是指子类重新实现父类中已有的方法,此方法可使用 @Override 注解来标记(非强制)。子类的方法必须与父类被重写的方法具有相同的名称、返回类型和参数列表。

重写,顾名思义就是重新编写原来的代码。Java 中重写的目的是让子类能够重新定义父类中已有的方法,从而实现多态性。通过重写,子类可以根据自己的需求来实现继承自父类的方法,使得代码更加灵活和可复用。同时,重写也可以提高程序的可读性和维护性。但是要注意一点,重写并不代表子类再也无法调用父类中被重写的方法了,子类仍可以通过 super 关键字进行调用。

重写必须满足以下规则:

  • 参数列表不能改变;
  • 返回类型可以为被重写方法的派生类(java5及之前版本完全不能改变);
  • 实现过程可以改变;
  • 异常声明不能比父类更加宽泛;
  • 访问限制不能比父类更加严格;
  • final 修饰的方法不可重写!
  • static 修饰的方法不可重写,但能重新声明!
  • 构造方法不可重写!
  • 父类无法被子类访问的方法不可重写!

总结:外壳(几乎)不能改变,内核可以改变。

重写可以说是父类方法的特化,所以从代码的具体程度上来说,子类重写后方法的具体程度比父类的更加大,自然而然地,重写后的方法抛出异常的声明不能比父类的更加宽泛。当然,父类中有些方法子类无法访问到,那么也就不存在所谓的重写。

特别说明一下,static 修饰的父类方法是不可重写的,子类照着父类的去”重写“也并非真正的重写,尽管程序可以运行。子类实际上只是重新声明,定义了一个新的、独立于父类的静态方法,对于父类的那个同名方法,只是相当于把它”隐藏“起来了而已,并没有真的重写。父类无法被子类访问的方法也是类似的道理,都是子类重新定义了一个新的方法罢了。

下面是一个简单的重写示例:

class Animal {
    public static void move() { // static 修饰,不可被重写
        System.out.println("动物移动");
    }

    public void bark() { // 被重写方法
        System.out.println("动物叫");
    }
}

class Dog extends Animal {
    // @Override // 错误的重写,添加注解则编译器报错
    public static void move() { // 重新声明,并非重写
        System.out.println("狗跑");
    }

    @Override // 重写注解
    public void bark() { // 重写方法
        System.out.println("狗吠");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = new Dog();
        Animal.move(); // Output:动物移动
        Dog.move(); // Output:狗跑
        animal.bark(); // Output: 动物叫
        dog.bark(); // Output: 狗吠
    }
}

@Override 注解

@Override 是一种注解(Annotation),它用于标记一个方法是重写了父类或接口了的同名方法。使用 @Override 注解可以让编译器检查该方法是否正确地重写了父类中的方法。如果没有正确重写,则编译器会提示错误。

注解 @Override 通常会用于下面两种情况:

  1. 子类重写父类方法时使用,以保证正确地重写,若错误重写(不满足规则)则编译报错;
  2. 重写接口中的抽象方法时使用, 以确保实现了接口中的所有抽象方法;

虽然注解 @Override 并非强制使用的,但加上它可以提高代码的可读性和可维护性,我们应该养成使用 @Override 的好习惯。

其他编程语言中的重写

在 Python 里面的重写非常直白,没有任何特殊的要求,只要子类与父类的方法同名,就可以重写。而 C++ 里的重写和 Java 也比较相似。

区别与联系

下面是一张总结性的表格: 

方式重载(overload)重写(override)覆写(overwrite)
参数列表必须改变不能改变\
返回类型可以改变(几乎)不能改变\
实现过程可以改变可以改变\
异常声明可以改变不能比父类更加宽泛\
访问限制可以改变不能比父类更加严格\
备注

final 关键字修饰的方法不可重写

子类无法访问的父类方法不可重写

static 关键字修饰的方法不可重写,但可重新声明

构造方法不可重写

\
总结外壳必须改变,内核可以改变

外壳(几乎)不能改变,内核可以改变

\

下面一张图片生动地展示了什么是重载和重写:

重载和重写

这里要特别强调的是,Java 中的构造方法只能被重载而不能被重写:

子类构造方法可以与父类构造方法同名,但参数列表必须不同,这就是方法重载的特性。子类构造方法可以调用父类构造方法来初始化从父类继承下来的属性或行为,即使用 super 关键字来调用父类的构造方法。重写是指子类重写了父类中已有的方法,并且方法名、参数列表和返回值类型都相同,在调用该方法时会优先调用子类中的方法而非父类中的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/648094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海思平台上USB WIFI的移植与局域网无线调试和视频流预览

目录 1.海思平台上USB WIFI移植概述 1.1、移植WIFI背景 1.2、移植的起点 1.3、实验案例 2.AP模式USB WIFI驱动移植 2.1、源码 2.2、修改移植 3.AP模式USB WIFI传输视频实战 3.1、部署USB WIFI驱动使之工作为AP 3.2、准备测试用例 3.3、测试实验 4.USB WIFI做sta模式…

python函数详解(超详细)

❄️作者介绍:奇妙的大歪❄️ 🎀个人名言:但行前路,不负韶华!🎀 🐽个人简介:云计算网络运维专业人员🐽 前言 首先零基础是能学python的,很多编程大神入门之前…

Qt中的坐标体系和内存回收

目录 坐标体系 窗口的坐标原点 窗口的相对坐标 示例 内存回收 1. 自动垃圾回收机制 2. 对象树机制 示例 坐标体系 窗口的坐标原点 在Qt中,坐标系统一般是以窗口左上角为原点,向右为正方向X轴,向下为正方向Y轴。 窗口的相对坐标 在一个…

node.js+vue企业人事管理系统q731f

中小企业人事管理系统的主要开发目标如下: (1)实现管理系统信息关系的系统化、规范化和自动化; (2)减少维护人员的工作量以及实现员工对信息的控制和管理。 (3)方便查询信息及管理信…

chatgpt赋能python:Python编程中的警告是什么?

Python编程中的警告是什么? 在Python编程中,警告是指在程序运行时出现的一些提示信息。这些警告通常不会导致程序崩溃,但却表明程序中存在某些问题。例如,警告可以是一个不推荐使用的语法或者可能导致性能退化的某个编码模式。通…

发布关于Strve.js的动态,被Vite团队核心成员点赞的那些事!

近日,在浏览之前发的推特文章时,发现了曾经被Vite团队核心成员 Matias Capeletto 点赞的一篇动态,心里格外的高兴。 被大佬认可,也是值得开心的一件事情。毕竟独立开发一个前端框架,其中的艰辛也只有像参与过类似设计框…

IAB讨论互联网碎片化:互操作性是互联网的关键属性

日前,一场针对互联网碎片化的讨论由互联网体系结构委员会(IAB)发起,主题涉及互联网碎片化的定义、概念、治理方式与未来发展。互联网治理论坛(IGF)咨询顾问维姆德格泽尔与大西洋理事会成员康斯坦丁诺斯科迈…

我的个人网站 —— 直接使用GPT4

前期回顾 打造极简风格动效 —— 5 分钟轻松实现惊艳、震撼人心的视觉效果_彩色之外的博客-CSDN博客css Loading 实战教学https://blog.csdn.net/m0_57904695/article/details/131156011?spm1001.2014.3001.5501 目录 ✈ 线上预览: ✅ G4 WEB 效果图例 &…

chatgpt赋能python:Python函数用法查看指南

Python函数用法查看指南 对于Python程序员来说,熟练查看函数用法是必不可少的技能。无论是入门级的学习者还是有多年编程经验的工程师都需要时常查看函数用法,以确保程序的正确性与效率。在本篇文章中,我们将介绍Python函数用法的常用方法与…

chatgpt赋能python:Python如何放在桌面:简单步骤和相关应用

Python如何放在桌面:简单步骤和相关应用 如果你是一名Python程序员,想要将Python放在桌面上以便在日常工作中更快捷地打开,并增强开发效率,那么这篇文章就是为你准备的。在这里,我们将介绍如何将Python安装在桌面上、…

chatgpt赋能python:Python怎么查找序列中的数字

Python怎么查找序列中的数字 在Python编程中,要查找序列中的数字是非常常见的任务。比如,我们需要查找一个列表中是否包含某个数字,或者在一个字符串中查找某个数字的出现次数等等。本文将介绍Python中查找序列中数字的几种方法,…

chatgpt赋能python:Python如何横排输出:实现方法详解

Python如何横排输出:实现方法详解 Python是一种高级编程语言,非常适合初学者入门。Python有很多应用程序领域,例如Web开发、数据分析、人工智能和机器学习等。在这些领域中,输出排版和显示的格式都十分重要。在某些情况下&#x…

C++静态转换

目录 1.1基本类型间的转换 1.2指针转换的限制 1.3空指针的转换 1.4弃值表达式 1.5左值转到右值 1.6类层次结构基类和派生类间的指针或引用转换 用法&#xff1a;static_cast<type_name> (expression) 说明&#xff1a;该运算符把expression转换为type_name类型stat…

ElasticSearch核心详解、文档、查询响应、分页、映射、结构化查询

目录 ElasticSearch核心详解文档元数据&#xff08;metadata&#xff09;index_type_id 查询响应pretty指定响应字段判断文档是否存在 批量操作批量查询_bulk操作 分页映射创建明确类型的索引&#xff1a;测试搜索 结构化查询term查询terms查询range查询exists 查询match查询bo…

Linux 虚拟文件系统 VFS 源码剖析

转自&#xff1a;Linux 虚拟文件系统 VFS 源码剖析 -- 以 ext4 为例&#xff08;Part1&#xff09; - 知乎 虚拟文件系统&#xff08;Virtual File System, VFS&#xff09;是 Linux 内核的一个组件&#xff0c;用于处理与文件和文件系统相关的所有系统调用。VFS 是内核提供文…

架构师怎样绘制系统架构蓝图?

首先&#xff0c;请你设想这样一个场景&#xff1a;如果公司安排你做架构师&#xff0c;要你在项目开发前期进行软件架构设计&#xff0c;你该如何开展你的工作&#xff1f;如何输出你的工作成果&#xff1f;如何确定你的设计是否满足用户需求&#xff1f;你是否有把握最后交付…

人工智能导论复习

Sell Out - Twoset Violin - 单曲 - 网易云音乐 (163.com) 目录 1 归结演绎推理 子句集&#xff1a; 归结&#xff1a; 2 可信度分析 CF模型 加权的不确定性推理 3 模糊推理-构造 扎德方法构造模糊关系 4 A* 5 遗传算法 6 神经网络 1 归结演绎推理 归结推理&#xff…

【ZooKeeper快速入门】 —— 每天一点小知识

&#x1f4a7; Z o o K e e p e r 快速入门 \color{#FF1493}{ZooKeeper快速入门} ZooKeeper快速入门&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 《数据结构与算法》专…

GPU 并行计算入门

文章目录 0. 前言1. CPU vs GPU2. 并行计算简介3. CUDA 简介4. CUDA 的处理流程 0. 前言 在没有GPU之前&#xff0c;基本上所有的任务都是交给CPU来做的。有GPU之后&#xff0c;二者就进行了分工&#xff0c;CPU负责逻辑性强的事物处理和串行计算&#xff0c;GPU则专注于执行高…

chatgpt赋能python:Python如何横着输入优化网站SEO

Python如何横着输入优化网站SEO 简介 Python作为一种强大的编程语言&#xff0c;在网络开发、数据处理、机器学习、人工智能等领域得到了广泛应用。随着互联网的发展&#xff0c;优化网站SEO已成为网站管理者不可或缺的重要职责&#xff0c;而如何横着输入也是优化SEO的重要一…