java中抽象类继承抽象类_用Java中的抽象类扩展抽象类
java中抽象类继承抽象类
示例问题
当我创建Java :: Geci抽象类AbstractFieldsGenerator
和AbstractFilteredFieldsGenerator
我遇到了一个不太复杂的设计问题。 我想强调一下,这个问题和设计对于某些人来说似乎很明显,但是在我最近与一位初级开发人员(我的儿子Mihály的交谈)中,我的文章比我的英语要好得多,意识到这个话题可能仍然有价值。
无论如何。 我有这两个类,字段和过滤字段生成器。 第二堂课扩展了第一堂课
abstract class AbstractFilteredFieldsGenerator extends AbstractFieldsGenerator {...
添加额外的功能,同时应为具体实现提供相同的签名。 这是什么意思?
这些生成器使用反射帮助生成特定类的代码。 因此,他们处理的输入信息是Class
对象。 字段生成器类具有一个抽象方法process()
,该方法将为每个字段调用。 它是从实现的方法中调用的,该方法遍历字段并分别对每个字段进行调用。 当具体类extends AbstractFieldsGenerator
并由此实现此抽象方法时,它将被调用。 当更改相同的具体类以使其extends AbstractFilteredFieldsGenerator
,将仅为过滤的方法调用具体方法。 我想要一个设计,以便在具体课程中唯一需要更改的是更改名称。
问题定义 类
以更抽象的方式描述相同的问题:有两个抽象类A
和F
以便F extends A
和F
提供一些额外的功能。 两者都声明了具体类应实现的抽象方法m()
。 当具体的类C
声明从C extends A
到C extends F
到C extends F
时,方法m()
的调用应更改,但类C
不应进行其他更改。 从类A
定义的方法p()
调用方法m()
。 如何设计F
?
这是什么问题?
可以通过两种明显不同的方式来扩展A
:
F
覆盖m()
使它混凝土在实施额外的功能m()
并调用新的抽象方法,说mx()
F
使用提供额外功能的版本覆盖方法p()
(在上面的示例中进行过滤),并调用仍然抽象的方法m()
第一种方法不能满足由具体类C
实施的签名应保持相同的要求。 第二种方法将A
的已经实现的功能扔给垃圾并以不同的方式重新实现它。 实际上,这是可能的,但是肯定会进行一些复制/粘贴编程。 这是有问题的,让我不解释原因。
问题的根源
在工程中,当我们面对这样的问题时,通常意味着问题或结构没有得到很好的描述,解决方案位于完全不同的区域中。 换句话说,有些假设驱动我们的思维方式是错误的。 在这种情况下,问题在于我们假设抽象类提供了一个扩展“ API”来对其进行扩展。 请注意,API不仅可以调用。 对于抽象类,扩展该抽象类时要实现的API。 正如库可以为使用不同的方式提供不同的API(Java 9 HTTP客户端可以send()
以及sendAsync()
)一样,抽象(实际上也是非抽象的)类也可以提供不同的扩展方式。用于不同的目的。
如果不修改A
就无法编码F
达到我们的设计目标。 我们需要一个A
版本,该版本提供不同的API来创建具体的实现,并提供另一个(不一定是正交/正交)来创建静态抽象的扩展。
在这种情况下,API之间的区别在于,具体实现的目标是在调用链的末尾,而抽象扩展则希望钩在调用链的最后一个元素上。 A
的实现必须提供要挂接到调用链的最后一个元素上的API。 这已经是解决方案。
解
我们在类F
实现方法ma()
,我们希望p()
调用我们的ma()
而不是直接调用m()
。 修改A
我们可以做到。 我们在A
定义ma()
,然后从p()
调用ma()
p()
。 在A
实现的ma()
版本应毫不费力地调用m()
,以为A
具体实现提供原始的“ API”。 F
中ma()
的实现包含额外的功能(在示例中为过滤),然后调用m()
。 这样,任何具体的类都可以扩展A
或F
并可以使用完全相同的签名实现m()
。 除了调用m()
是与ma()
的两个版本相同的代码外,我们还避免了复制/粘贴编码。
如果我们希望类F
具有更多抽象类可扩展性,则F::ma
实现不应直接调用m()
,而应调用m()
的新mf()
m()
。 这样,新的抽象类可以覆盖mf()
从而再次提供新功能并调用抽象m()
。
带走
- 对抽象类进行编程非常复杂,有时很难清楚地了解谁在调用谁以及哪种实现。 如果您意识到这可能是一件复杂的事情,则可以克服这一挑战。 记录,可视化,讨论可以帮助您的任何方式。
- 当您不能解决问题时(在示例中,如何对
F
进行编码),您应该挑战环境(我们隐式地认为问题A
的类A
是不变的:“如何实现F
?”)。 - 避免复制/粘贴编程。 (面食包含大量CH,使您的代码变胖,动脉阻塞,最后,应用程序的心脏将停止跳动。)
- 尽管在本文中没有详细介绍,但是请注意,抽象层次越深,要清楚地了解谁来呼叫谁就越困难(另请参见第1点)。
- 在https://github.com/verhas/abstractchain中找到示例演示应用程序
- 在https://github.com/verhas/javageci上找到具有这种模式的原始的,有点复杂的应用程序
翻译自: https://www.javacodegeeks.com/2019/06/extending-abstract-classes-with-abstract-classes-in-java.html
java中抽象类继承抽象类
java中抽象类继承抽象类_用Java中的抽象类扩展抽象类相关推荐
- 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目
王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...
- java抽象类数组初始化_【Java抽象类 11】
一.抽象类 1.语法,在class关键字前边添加abstract关键字 2.抽象类无法实例化,但是抽象类中仍然有构造方法 3.抽象类中不一定有抽象方法,但是抽象方法必须出现在抽象类中 4.抽象方法修饰 ...
- java 继承变量_用java中的变量继承
任何人都可以澄清我.这里实例方法被覆盖但变量不被覆盖. 输出为:B 10 class A{ int i=10; public void name(){ System.out.println(" ...
- java 重写方法 访问权限_为何Java中子类重写方法的访问权限不能低于父类中权限(内含里氏替换原则)...
为何Java中子类重写方法的访问权限不能低于父类中权限 因为 向上转型及Java程序设计维护的原因 例: 假设一个父类A 拥有的方法public void setXXX(){}可以被其他任意对象调用这 ...
- java项目中多个定时器_在java项目中如何使用Timer定时器
在java项目中如何使用Timer定时器 发布时间:2020-11-16 16:36:16 来源:亿速云 阅读:97 作者:Leah 在java项目中如何使用Timer定时器?很多新手对此不是很清楚, ...
- JAVA设计一个电视机类_漫谈Java程序设计中的接口应用
Java语言提供了一种接口(interface)机制.这种接口机制使Java的面向对象编程变得更加灵活.我们可以用接口来定义一个类的表现形式,但接口不能包含任何实现.在<Thinking in ...
- java中井号字符串_深入Java基础(二)——字符串
这段时间在准备找一份java实习工作,所以来把基础知识整理归纳一下 文章结构: 1.equals和== 2.字符串的基本知识以及字符串的源码解读: 3.字符串的注意点以及使用推荐: 一.equals和 ...
- java中字符流 字节流_理解Java中字符流与字节流的区别
1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可 ...
- java根据父类找子类_在java中实现多态时,可以通过父类变量引用子类的对象。_学小易找答案...
[单选题]对于字符串s="java",下面哪个选项返回字符在字符串中'v'的位置( ). [简答题]汽车核保的主要内容 [判断题]在java中产生子类对象时,直接调用子类的构造方法 ...
- java中各种vo举例_了解JAVA中的POJO,Entity,PO,VO,DTO,DM包括代码举例展示
标签: 首先是从概念上来说 POJO,全称Plain Ordinary Java Object,我理解为极其单纯的Java对象 一般只有属性字段,无参构造以及get和set方法,也是指那些没有从任何类 ...
最新文章
- ​Python数据可视化工具怎么选?深度评测5款实用工具
- 深度 | 谷歌的新CNN特征可视化方法,构造出一个华丽繁复的新世界
- 白话Elasticsearch45-深入聚合数据分析之易并行聚合算法,三角选择原则,近似聚合算法
- Java 基本数据类型
- net_conv1_conv2_conv3_conv4_py
- IOS14.3开发之使用纯代码创建UIButton以及弹框的使用
- CTF-Crypto密码学
- Windows 2000缓冲区溢出技术原理
- C语言字符串库函数的实现
- 华为手机如何调时间显示_华为手机不亮屏也能显示时间日期?10秒就能设置,原来这么简单...
- ssh无密码登录设置
- 全网首发:CENTOS FreeSwitch集成NVIDIA CODEC
- JAVA菜鸟的第一天
- 下三角99乘法表 C语言
- 软件实施工程师需要掌握的技能
- ERP : 出版行业解决方案
- ubuntu 18.04 VSCode沙绿色主题设置
- int 和 Integer有什么区别,Integer 有哪些函数方法
- Bless You Autocorrect!(字典树上建图)
- 软件设计师考试(2018下半年)
热门文章
- E - Another Postman Problem FZU - 2038
- 牛客题霸 [输出二叉树的右视图] C++题解/答案
- [WF2011] MachineWorks(李超树优化dp)
- 多重背包的二进制优化(ybtoj-宝物筛选)
- CF990G-GCD Counting【dfs】
- Comet OJ(Contest #8)-D菜菜种菜【树状数组,指针】
- jzoj3464-秀姿势【hash】
- jzoj1013-GCD与LCM【数论】
- ssl初一组周六模拟赛【2018.4.21】
- 纪中A组模拟赛总结(2021.7.12)