1

给定 OOP 语言中的一组元组类:Pair、Triple 和 Quad,Triple 应该是 Pair 的子类,Quad 是 Triple 的子类吗?

在我看来,问题在于 Triple 是否可以替代为 Pair,Quad 也可以替代 Triple 或 Pair。Triple是否也是一对,Quad是否也是Triple 和 Pair。

在一种情况下,这样的关系可能对可扩展性很有价值——今天这个东西返回一个 Pair of things,明天我需要它返回一个 Triple 而不破坏现有的调用者,他们只使用三个中的前两个。

另一方面,它们应该是不同的类型吗?我可以看到更强类型检查的好处——你不能将 Triple 传递给需要 Pair 的方法。

我倾向于使用继承,但真的很感谢其他人的意见吗?

PS:如果重要的话,课程(当然)将是通用的。

PPS:在更主观的方面,名称应该是 Tuple2、Tuple3 和 Tuple4 吗?


编辑:我认为这些更像是松散耦合的组;不是专门用于 x/yx/y/z 坐标之类的东西,尽管它们可能用于此类。这就像需要一个方法的多个返回值的通用解决方案,但形式具有非常简单的语义。

也就是说,我对其他人实际使用元组的所有方式都很感兴趣。

4

6 回答 6

1

在我看来,您应该制作一个通用的 Tuple 接口(或使用类似于上面提到的 Collection 的东西),并让您的 pair 和 3-tuple 类实现该接口。这样,您可以利用多态性,但也允许一对使用比任意大小的元组更简单的实现。您可能希望让您的 Tuple 接口包含 .x 和 .y 访问器作为前两个元素的简写,并且较大的元组可以根据具有较高索引的项目实现自己的简写。

于 2009-02-12T03:39:29.543 回答
1

这取决于您需要的语义 -

  • 一对对立面在语义上与相似对象的 3 元组不兼容
  • 极坐标空间中的一对坐标与欧几里得空间中的三元组坐标在语义上不兼容

如果您的语义是简单的组合,那么泛型类 Tuple<N> 会更有意义

于 2009-02-12T04:27:05.857 回答
1

不同长度的元组是不同的类型。(好吧,无论如何,在许多类型系统中。)在强类型语言中,我认为它们不应该是一个集合。

这是一件好事,因为它确保了更多的安全性。返回元组的地方通常有一些耦合信息,即每个组件是什么的隐含知识。如果你在一个元组中传递的值比预期的多,那就更糟了——这应该是什么意思?它不适合继承。

另一个潜在问题是您是否决定使用重载。如果元组相互继承,则重载解析将在不应该的地方失败。但这可能是反对重载的更好论据。

当然,如果您有特定的用例并发现某些行为会对您有所帮助,那么这些都不重要。

编辑:如果您想了解一般信息,请尝试阅读一些 Haskell 或 ML 系列 (OCaml/F#) 以了解它们是如何使用的,然后形成您自己的决定。

于 2009-02-12T05:09:42.073 回答
1

像大多数与设计相关的问题一样,答案是——视情况而定。

如果您正在寻找传统的 Tuple 设计,Tuple2、Tuple3 等是您的选择。继承的问题在于,首先 Triplet 不是 Pair 的一种。你将如何为它实现 equals 方法?Triplet 是否等于前两项相同的 Pair?如果你有一个 Pairs 的集合,你可以添加三元组,反之亦然?如果在您的域中这很好,您可以使用继承。

无论如何,拥有所有这些实现的接口/抽象类(可能是元组)是值得的。

于 2009-02-12T05:31:05.377 回答
0

我会选择 0,1,2 或无穷大。例如 null、1 个对象、您的 Pair 类,或者某种集合。

你的 Pair 甚至可以实现一个 Collection 接口。

如果三个或四个项目之间存在特定的关系,它可能应该被命名。

[也许我错过了这个问题,但我想不出一个我想以通用方式专门链接 3 件事的情况]

于 2009-02-12T03:12:45.380 回答
0

Gilad Bracha写了一篇关于 tuples 的博客,我觉得读起来很有趣。

他提出的一点(无论是否正确,我还无法判断)是:

文字元组最好定义为只读。原因之一是只读元组更具多态性。长元组是短元组的子类型:

{STU V} <= {ST U} <= {S。T} <= {S}

[和] 只读元组是协变的:

T1 <= T2,S1 <= S2 ==> {S1. T1} <= {S2。T2}

这似乎表明我使用继承的倾向可能是正确的,并且当 amit.dev 说 Triple不是Pair 时会与他相矛盾。

于 2009-02-12T07:38:16.787 回答