【问题标题】:Same properties introduced in various descendant classes在各种后代类中引入的相同属性
【发布时间】:2017-01-24 23:01:35
【问题描述】:

我正在使用 Delphi,但故意不希望您坚持使用特定语言,因为问题是基本问题。

我的应用程序现在包含各种类型的数据记录列表。每条记录都有一组不同的属性。此时,所有记录在 RAM 中都由同一通用类的对象表示。里面有一个字段,代表一个记录类型,getter/setter根据这个字段的内容来锁定和解锁数据的检索或更改。

我计划开发一个使用多态性的严格架构,其中每个记录类型将由相应的后代类表示。父类不会包含任何后代特定的属性,而只会包含常见的属性。

现在,问题来了:

一些可用属性存在于几个后代类中,但不应出现在基类中。它们的 getter 和 setter 是相同的。如何不重复自己并为每个属性编写一个 getter 和一个 setter?

我想到的唯一想法是将基类中的所有属性实现为受保护,然后将它们移动到后代类中的公共部分。

您认为这个解决方案是好是坏?为什么?

还有其他方法可以实现目标吗?

插图:

class Base
   prop A
   prop B

class Desc1:Base
   prop C
   prop D

class Desc2:Base
   prop D
   prop E

class Desc3:Base
   prop C
   prop E

【问题讨论】:

  • 通过属性,你的意思是什么?函数、过程、变量?
  • 他最有可能表示该类的成员,例如id
  • @cedric.salaun:在 Delphi 或 C# 等许多编程语言中,有一种名为属性的特殊类成员。它们看起来像变量,但实际上调用方法。

标签: inheritance polymorphism


【解决方案1】:

您的想法不好,因为通过保护某些属性,您强制将它们包含在 all 子类中,这显然是不正确的。此外,如果子类数量增加,您将不得不在基类中包含越来越多的属性。

您可以做的是引入允许多重继承或混入的抽象:

  • C++ 中的(抽象)类
  • Java 接口
  • Scala 中的特征

将包含属性CDE 之一。 例如:

interface CHolder
    prop C

interface DHolder
    prop D

interface EHolder
    prop E

现在您可以让DescN 扩展所需的抽象:

class Base
   prop A
   prop B

class Desc1:Base, CHolder, DHolder

class Desc2:Base, DHolder, EHolder

class Desc3:Base, CHolder, EHolder

【讨论】:

    【解决方案2】:

    首先,我不了解 Delphi,但您声称我们不应该考虑它。在纯 OOP 下,您将创建一个具有共享属性的超类,但前提是子类之间具有逻辑链接。例如。 Dog 和 Cat 都是 Animal,Animal 可以拥有由 Dog、Cat 和通常是 Animal 共享的属性 hasTail。然而,Plane 不会扩展 Animal,尽管也有 hasTail 属性。

    但是,纯粹的 OOP 并不总是实用的(例如,如果您以深度为 200 的继承树结束)。我建议,除非有大量共享属性,而且更好的是,将它们分组到一个超类中是有意义的。你只是硬着头皮输入额外的访问器。

    如果有大量共享属性,但类不应扩展同一个类(因为 Cat 和 Plane),您可以查看接口。接口定义了您要公开的行为,该行为由不应由超类分组的许多类共享(再次,Cat 和 Plane 可以具有 Turn、Forward、SlowDown、AcceptPassengers 以及接口 PublicTransport 上的任何内容)。它不会节省您的打字时间,但它是“正确的方式”。

    检查 Delphi 是否有一个 IDE,它允许您生成所有这些访问器,而无需您执行任何操作,只需单击几下。 Java 可以。在这种情况下,您将为这些类中的每一个都有一个文件,现在称为“bean”,它只有属性和自动生成的访问器。如果可能的话,你在其他地方有更多的动手逻辑。这样,您只需在需要添加/删除属性时编辑 bean。

    如果没有,并且共享属性的数量很大,请随意做你想做的事,但要留下很多 cmets,因为任何必须维护它的人(包括未来的你)都会遇到麻烦。

    您可以拥有一个属性“properties”,其映射为“propertyname”->“value”。并在构造函数上定义属性列表,在基类上只有一个通用的 getter 和 setter。但那是如果您不希望语言为您处理检查,并且希望对您想要拥有的属性持开放态度。

    【讨论】:

    • 明智的回答。谢谢。
    猜你喜欢
    • 2016-08-30
    • 2011-01-12
    • 1970-01-01
    • 2013-12-31
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    相关资源
    最近更新 更多