当前位置: 首页 > 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 个空瓶子。…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

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

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