java中抽象类继承抽象类

示例问题

当我创建Java :: Geci抽象类AbstractFieldsGeneratorAbstractFilteredFieldsGenerator我遇到了一个不太复杂的设计问题。 我想强调一下,这个问题和设计对于某些人来说似乎很明显,但是在我最近与一位初级开发人员(我的儿子Mihály的交谈)中,我的文章比我的英语要好得多,意识到这个话题可能仍然有价值。

无论如何。 我有这两个类,字段和过滤字段生成器。 第二堂课扩展了第一堂课

 abstract class AbstractFilteredFieldsGenerator extends AbstractFieldsGenerator {... 

添加额外的功能,同时应为具体实现提供相同的签名。 这是什么意思?

这些生成器使用反射帮助生成特定类的代码。 因此,他们处理的输入信息是Class对象。 字段生成器类具有一个抽象方法process() ,该方法将为每个字段调用。 它是从实现的方法中调用的,该方法遍历字段并分别对每个字段进行调用。 当具体类extends AbstractFieldsGenerator并由此实现此抽象方法时,它将被调用。 当更改相同的具体类以使其extends AbstractFilteredFieldsGenerator ,将仅为过滤的方法调用具体方法。 我想要一个设计,以便在具体课程中唯一需要更改的是更改名称。


问题定义

以更抽象的方式描述相同的问题:有两个抽象类AF以便F extends AF提供一些额外的功能。 两者都声明了具体类应实现的抽象方法m() 。 当具体的类C声明从C extends AC extends FC 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”。 Fma()的实现包含额外的功能(在示例中为过滤),然后调用m() 。 这样,任何具体的类都可以扩展AF并可以使用完全相同的签名实现m() 。 除了调用m()是与ma()的两个版本相同的代码外,我们还避免了复制/粘贴编码。

如果我们希望类F具有更多抽象类可扩展性,则F::ma实现不应直接调用m() ,而应调用m()的新mf() m() 。 这样,新的抽象类可以覆盖mf()从而再次提供新功能并调用抽象m()

带走

  1. 对抽象类进行编程非常复杂,有时很难清楚地了解谁在调用谁以及哪种实现。 如果您意识到这可能是一件复杂的事情,则可以克服这一挑战。 记录,可视化,讨论可以帮助您的任何方式。
  2. 当您不能解决问题时(在示例中,如何对F进行编码),您应该挑战环境(我们隐式地认为问题A的类A是不变的:“如何实现F ?”)。
  3. 避免复制/粘贴编程。 (面食包含大量CH,使您的代码变胖,动脉阻塞,最后,应用程序的心脏将停止跳动。)
  4. 尽管在本文中没有详细介绍,但是请注意,抽象层次越深,要清楚地了解谁来呼叫谁就越困难(另请参见第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中的抽象类扩展抽象类相关推荐

  1. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  2. java抽象类数组初始化_【Java抽象类 11】

    一.抽象类 1.语法,在class关键字前边添加abstract关键字 2.抽象类无法实例化,但是抽象类中仍然有构造方法 3.抽象类中不一定有抽象方法,但是抽象方法必须出现在抽象类中 4.抽象方法修饰 ...

  3. java 继承变量_用java中的变量继承

    任何人都可以澄清我.这里实例方法被覆盖但变量不被覆盖. 输出为:B 10 class A{ int i=10; public void name(){ System.out.println(" ...

  4. java 重写方法 访问权限_为何Java中子类重写方法的访问权限不能低于父类中权限(内含里氏替换原则)...

    为何Java中子类重写方法的访问权限不能低于父类中权限 因为 向上转型及Java程序设计维护的原因 例: 假设一个父类A 拥有的方法public void setXXX(){}可以被其他任意对象调用这 ...

  5. java项目中多个定时器_在java项目中如何使用Timer定时器

    在java项目中如何使用Timer定时器 发布时间:2020-11-16 16:36:16 来源:亿速云 阅读:97 作者:Leah 在java项目中如何使用Timer定时器?很多新手对此不是很清楚, ...

  6. JAVA设计一个电视机类_漫谈Java程序设计中的接口应用

    Java语言提供了一种接口(interface)机制.这种接口机制使Java的面向对象编程变得更加灵活.我们可以用接口来定义一个类的表现形式,但接口不能包含任何实现.在<Thinking in ...

  7. java中井号字符串_深入Java基础(二)——字符串

    这段时间在准备找一份java实习工作,所以来把基础知识整理归纳一下 文章结构: 1.equals和== 2.字符串的基本知识以及字符串的源码解读: 3.字符串的注意点以及使用推荐: 一.equals和 ...

  8. java中字符流 字节流_理解Java中字符流与字节流的区别

    1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可 ...

  9. java根据父类找子类_在java中实现多态时,可以通过父类变量引用子类的对象。_学小易找答案...

    [单选题]对于字符串s="java",下面哪个选项返回字符在字符串中'v'的位置( ). [简答题]汽车核保的主要内容 [判断题]在java中产生子类对象时,直接调用子类的构造方法 ...

  10. java中各种vo举例_了解JAVA中的POJO,Entity,PO,VO,DTO,DM包括代码举例展示

    标签: 首先是从概念上来说 POJO,全称Plain Ordinary Java Object,我理解为极其单纯的Java对象 一般只有属性字段,无参构造以及get和set方法,也是指那些没有从任何类 ...

最新文章

  1. ​Python数据可视化工具怎么选?深度评测5款实用工具
  2. 深度 | 谷歌的新CNN特征可视化方法,构造出一个华丽繁复的新世界
  3. 白话Elasticsearch45-深入聚合数据分析之易并行聚合算法,三角选择原则,近似聚合算法
  4. Java 基本数据类型
  5. net_conv1_conv2_conv3_conv4_py
  6. IOS14.3开发之使用纯代码创建UIButton以及弹框的使用
  7. CTF-Crypto密码学
  8. Windows 2000缓冲区溢出技术原理
  9. C语言字符串库函数的实现
  10. 华为手机如何调时间显示_华为手机不亮屏也能显示时间日期?10秒就能设置,原来这么简单...
  11. ssh无密码登录设置
  12. 全网首发:CENTOS FreeSwitch集成NVIDIA CODEC
  13. JAVA菜鸟的第一天
  14. 下三角99乘法表 C语言
  15. 软件实施工程师需要掌握的技能
  16. ERP : 出版行业解决方案
  17. ubuntu 18.04 VSCode沙绿色主题设置
  18. int 和 Integer有什么区别,Integer 有哪些函数方法
  19. Bless You Autocorrect!(字典树上建图)
  20. 软件设计师考试(2018下半年)

热门文章

  1. E - Another Postman Problem FZU - 2038
  2. 牛客题霸 [输出二叉树的右视图] C++题解/答案
  3. [WF2011] MachineWorks(李超树优化dp)
  4. 多重背包的二进制优化(ybtoj-宝物筛选)
  5. CF990G-GCD Counting【dfs】
  6. Comet OJ(Contest #8)-D菜菜种菜【树状数组,指针】
  7. jzoj3464-秀姿势【hash】
  8. jzoj1013-GCD与LCM【数论】
  9. ssl初一组周六模拟赛【2018.4.21】
  10. 纪中A组模拟赛总结(2021.7.12)