java抽象类扩展_用Java中的抽象类扩展抽象类

java抽象类扩展

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://www.javacodegeeks.com/2019/06/extending-abstract-classes-with-abstract-classes-in-java.html

java抽象类扩展

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值