当前位置: 首页 > news >正文

关于Java方法重写的一些反思

最近在开发中遇到一个关于Java方法重写的一些问题,对于方法重写的用法以及可能导致的问题产生了一些思考,本文用于记录下这些想法。

问题场景

我们首先来看两段代码:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode){case TAKE_PHOTO_CODE:{//处理拍照得到的结果break;}case CHOOSE_FROM_ALBUM_CODE:{//处理相册选取到的结果break;}}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {switch (requestCode){case TAKE_PHOTO_CODE:{//处理拍照得到的结果break;}case CHOOSE_FROM_ALBUM_CODE:{//处理相册选取到的结果break;}default:{super.onActivityResult(requestCode, resultCode, data);}}
}

这两段代码是Android开发中处理Activity结果的示例。Android启动新页面后,新页面设置完结果返回的时候,旧页面可以从这个方法得到新页面的结果。来自不同页面的结果按照参数中的requestCode来区分,这个requestCode和启动新页面时传递的对应,也就是说一个requestCode标识一个页面请求和一个结果类型。例如,上面示例模拟的是常见APP中换用户头像的功能,结果有两种:1. 拍照得到的结果;2. 相册选取得到的结果。

上面两种方法就结果来说都是对的,但是表达的意义不同:第一种写法是纯粹地扩展父类的方法,父类干的事它都干;而第二种写法是改写父类的方法,相当于重定义并依赖了父类的行为,或者说对父类行为做了拦截、访问控制。

原本Activity类中默认实现是个空方法:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}

这种情况下两种写法的行为差异完全可以忽略不计,但是实际开发中我们一般继承自FragmentActivityAppCompatActivity,这两个类都对这个方法做了相应的实现,在这种情况下,第一种写法父类的实现一定会被执行,但是第二种写法可能将父类的实现短路了。这可能导致一些意料之外的问题,比如,Activity和Fragment都对某个requestCode进行处理,但第二种写法会导致Fragment的对应onActivityResult方法不会被掉用。

在实际开发中我们可能会编写一个BaseActivity,将一些方法实现一下并添加统计和日志,那么第二种写法也可能导致日志丢失的问题。

问题分析

这个问题让我联想到一个设计原则:里氏替换原则(Liskov Substitution principle)。这个原则说明:派生类(子类)对象可以在程序中代替其基类(超类)对象。这表示程序中任何父类对象可以出现的位置,子类的对象都可将其替代。进一步解读,就是意味着子类可以扩展父类的功能,但不能改变父类原有的功能。

这个原则考虑了安全性。编程时为了降低耦合度,通常面向抽象数据类型(例如接口、抽象类等)来编写,而父类在编写的时候也不会去考虑子类的实现,那么就要求子类的实现的时候需要顾及父类的运行。

那么当我们在重写父类方法的时候,情况就复杂了起来,具体分为以下几种情况:

  1. 当父类代码和子类代码都是同一个人负责的时候,并且在代码同一项目、同一模块。这种情况比较安全,因为编写子类实现的人是完全了解并掌控父类实现的;
  2. 当父类代码和子类代码是同一个人负责的时候,而代码位于不同项目。例如,一个人同时维护一个应用项目和一个独立框架。这种情况,就可能出隐患,因为随着项目进行,这个框架中的父类可能被多个应用项目使用,这个父类就可能无法兼顾多个项目的场景和用法,而导致子类实现中错误地改写父类的方法。
  3. 当父类代码和子类代码时不同的人负责,且代码位于不同项目时,这种情况就比较危险了。因为父类实现的行为实现和行为变更很可能是不透明的、未知的,而且父类的实现可能不会顾及到子类的应用。那么当子类改写父类行为的时候,当父类行为发生变更,那么子类的实现很可能是有问题的。

方法与建议

针对上面所提到的三种情况,我思考了如下三个对应的建议:

  1. 针对第一种安全的情况,尽量不改写父类方法,在子类和父类实现中尽量补充注释和注解说明;
  2. 针对第二种有隐患的情况,尽量不改写父类方法,父类设计无法涵盖所有场景时,适当时候重构父类代码,而不是让子类通过“hack”的手段曲线救国。
  3. 针对第三种危险的情况,一定不要改写父类方法,可以考虑在方法第一行就super调用。

相关文章:

关于Java方法重写的一些反思

最近在开发中遇到一个关于Java方法重写的一些问题,对于方法重写的用法以及可能导致的问题产生了一些思考,本文用于记录下这些想法。 问题场景 我们首先来看两段代码: Override protected void onActivityResult(int requestCode, int resu…...

【C语言进阶】文件的顺序读写、随机读写、文本文件和二进制文件、文件读取结束的判定以及文件缓冲区相关知识

​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:C语言进阶 🎯长路漫漫浩浩,万事皆有期待 文章目录1.文件操作1.1 概述…...

图形编辑器:拖拽阻塞优化

大家好,我是前端西瓜哥。在图形编辑器中,想象这么一个场景,我们撤销了一些重要的操作,然后想选中一个图形,看看它的属性。你点了上去,然后你发现你再也无法重做了。 你以为你点了一下,但其实你…...

c++ 的 Eigen库写 AX=XB的矩阵求解代码

1.AXXB的矩阵求解代码(3*3) #include <iostream> #include <Eigen/Dense>int main() {// 定义矩阵A和BEigen::MatrixXd A(3, 3);A << 1, 2, 3,4, 5, 6,7, 8, 9;Eigen::MatrixXd B(3, 3);B << 10, 11, 12,13, 14, 15,16, 17, 18;// 求解AXXBEigen::Mat…...

正点原子linux驱动篇

linux驱动开发与裸机开发的区别 裸机直接操作寄存器&#xff0c;有些mcu提供了库&#xff0c;但还是很底层 1、linux驱动开发直接操作寄存器很麻烦不现实&#xff0c;主要是根据linux驱动框架进行开发&#xff08;就是有很多操作都是一样的&#xff0c;我们只需要对一个程序模…...

MATLAB绘制雷达图/蜘蛛图

雷达图/蜘蛛图 1 方法一 函数来源为MATLAB | 如何使用MATLAB绘制雷达图(蜘蛛图) 1.1 调用函数 1.2 案例 2 方法二 函数来源为MATLAB帮助-spider_plot 2.1 调用函数 语法&#xff08;Syntax&#xff09;&#xff1a; spider_plot(P)spider_plot(P, Name, Value, ...)h …...

算法入门,十字路口选择的案例,如果是南方,则向前行

从if判断start; 十字路口的案例 class HelloWorld { static void Main(string[] args) { /* Write C# code in this online editor and run it. */ Console.WriteLine("Hello World!"); string f…...

父传子与子传父步骤

父传子&#xff1a; 问题&#xff1a;父页面中引入子组件 把想要传给子页面的值用在子组件中用 &#xff1a;值“值” (用同一个值好区分)来绑定。 在子页面中用props接收 子组件不能改变父组件传过来的值。&#xff08;传多个页面的时候是&#xff0c;比如父传孙的时候我会…...

Java concurrency - Task Execution

1.在单个线程里处理所有的请求&#xff1a;接受请求-处理请求 优点&#xff1a;逻辑简单 缺点&#xff1a;吞吐量低&#xff0c;资源利用率低&#xff0c;响应时间长 2.每个任务分配一个单独的线程来处理&#xff1a; 接受请求-创建线程-在线程里处理请求 优点&#xff1a; …...

浅谈BOM

什么是BOM BOM对于每个前端都不陌生&#xff0c;但是很多人都停留在表面&#xff0c;而没有深层次的研究过它。JavaScript有一个非常重要的运行环境就是浏览器&#xff0c;而且浏览器本身又作为一个应用程序需要对其本身进行操作&#xff0c;所以通常浏览器会有对应的对象模型…...

每日学术速递2.24

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.LG 1.BUAA_BIGSCity: Spatial-Temporal Graph Neural Network for Wind Power Forecasting in Baidu KDD CUP 2022 标题&#xff1a;BUAA_BIGSCity&#xff1a;百度KDD CUP 2022风电预测…...

SpringBoot 面试问答总结(VIP典藏版)

1. 什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 开源组织下的子项目&#xff0c;是 Spring 组件一站式解决方案&#xff0c;主要是简化了使用Spring 的难度&#xff0c; 简省了繁重的配置&#xff0c;提供了各种启动器&#xff0c;使开发者能快速上手。 2. 为什…...

CSS 定位网页元素【快速掌握知识点】

目录 前言 一、position: static 二、position: relative 三、position: absolute 四、position: fixed 五、position: sticky 前言 当我们在设计网页时&#xff0c;经常需要对网页中的元素进行定位&#xff0c;以便它们出现在我们想要的位置。在 CSS 中&#xff0c;我们…...

构建Docker基础镜像(ubuntu20.04+python3.7.1+chrome101+chromedriver101)

文章目录 一、前置条件1.下载 chrome【google-chrome-stable_current_amd64.deb】2.下载 chromedriver【chromedriver_linux64.zip】3.创建 ubuntu 镜像源文件【sources.list】二、构建方法1.构建目录1.创建DockerFile2.打包镜像一、前置条件 要先下载一个支持 linux 的 浏览器…...

最新最全Java面试知识

工作也有好些年了&#xff0c;从刚毕业到前几年看过无数的面试题&#xff0c;在这个过程中也作为面试官面试过其他人&#xff0c;总想着自己写一个面试总结&#xff0c;随着自我认识的变化&#xff0c;一些知识点的理解也越来越不一样了。写下来温故而知新。很多问题可能别人也…...

个人电脑需求严重疲软,联想集团财务前景仍不乐观

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 财务业绩 联想集团&#xff08;00992&#xff09;于2月16日盘后公布了2023财年第三季度财报。 财报显示联想集团2023年第三季度的收入为152.67亿美元&#xff0c;从2022年第三季度的2011.27亿美元下降了24.1%。这也导致该公…...

软件测试面试在简历上写了“精通”后,拥有工作经验的我被面试官问到窒息...

前言 如果有真才实学&#xff0c;写个精通可以让面试官眼前一亮&#xff01; 如果是瞎写&#xff1f;基本就要被狠狠地虐一把里&#xff01; 最近在面试&#xff0c;我现在十分后悔在简历上写了“精通”二字… 先给大家看看我简历上的技能列表&#xff1a; 熟悉软件测试理…...

色环电容读数方法要点总结

🏡《总目录》 目录 1,概述2,读数方法3,颜色对照表3.1,颜色与电容值数字对照关系表3.2,颜色与10的指数数字对照关系表3.3,颜色与误差对照关系表4,总结1,概述 本文简单介绍色环电容的读数方法。 2,读数方法 如下图所示色环电容共有四个色环。最粗的被命名为第1环,依次…...

C++函数新思想和标准的输入和输出

欢迎来观看温柔了岁月.c的博客目前设有C学习专栏C语言项目专栏数据结构与算法专栏目前主要更新C学习专栏&#xff0c;C语言项目专栏不定时更新待C专栏完毕&#xff0c;会陆续更新C项目专栏和数据结构与算法专栏一周主要三更&#xff0c;星期三&#xff0c;星期五&#xff0c;星…...

华为OD机试真题Java实现【汽水瓶】真题+解题思路+代码(20222023)

汽水瓶 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是 5 瓶,方法如下:先用 9 个空瓶子换3瓶汽水,喝掉 3 瓶满的,喝完以后 4 个空瓶子,用 3 个再换一瓶,喝掉这瓶满的,这时候剩 2 个空瓶子。…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...