问题标签 [subtyping]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
4388 浏览

c++ - 派生类和基类之间的指针到指针的转换?

关于以下 C++ 程序:

GCC 在最后一个赋值语句中产生以下错误:

我的问题分为两部分:

  1. 为什么没有从 Child** 到 Base** 的隐式转换?
  2. 我可以让这个示例使用 C 风格的演员表或reinterpret_cast. 使用这些类型转换意味着抛弃所有类型安全。有什么我可以添加到类定义中以使这些指针隐式转换,或者至少以允许我使用的方式来表达转换static_cast
0 投票
1 回答
626 浏览

scala - Scala子类型+隐式转换问题

我正在尝试使用 scalaz 库对 scala 中的 monads 做一些事情,并且在使其与子类型很好地配合使用时遇到了一些麻烦。

我已经开始定义我自己的 monad。为了简单起见,让它成为一个身份单子:

接下来,我用一些额外的功能对其进行了扩展:

有了这个附加功能,ExtendedId不再是 monad。

现在我想将类型的对象ExtendedId[A]用作Id[A]

请注意,我知道由于ExtendedId不是​​ monad,所以我能得到的最好的输出是Id[Int],我可以接受!但不幸的是,该代码仍然无法编译。

但是,这个确实:

在这里,asId函数只是将其参数向上转换为 from ExtendedId[A]to Id[A]。似乎它应该是完全多余的,但事实并非如此。

为什么会这样?确实存在从Id[A]到包含的对象的隐式转换,map并且显然确实存在从ExtendedId[A]到的微不足道的隐式转换Id[A]。那么,为什么编译器无法组合它们呢?

0 投票
4 回答
3988 浏览

java - 我应该如何在 Java 中实现 Message 类的子类型?

我确信这是一个基本的 OOP 问题——我正在设计一个消息传递系统,其中有几种完全不同的消息格式,但我希望它们都能够放在 PriorityBlockingQueue 上。我的第一个想法是abstract class Message为每种消息类型定义一个然后定义扩展 Message 的子类。但这意味着,在接收端,消息处理器需要识别子类才能知道如何处理消息的内容。我知道这样做的唯一方法是使用.instanceof()orClass.并且它似乎不正确。

正如斯科特迈耶斯所写,

任何时候你发现自己在编写“如果对象是 T1 类型,则做某事,但如果它是 T2 类型,则做其他事情”形式的代码,给自己一记耳光。

(他继续指出,在多态中,你应该有相同的方法名称,每个子类有不同的实现。我不明白如何让这个想法在我的情况下发挥作用——消息类型本身是完全不相关的.)

为了讨论,这里是我的消息类型:

  • ConsoleMessage,标识一个 ConsoleObject 和一个 ObjectState。
  • CardReaderRequestMessage,不包含任何内容,只是请求“下一张卡片”
  • CardReaderMessage,包含一个 byte[80] 的卡片图像和一个 Last Card 指示符
  • CardPunchMessage,包含一个byte[80]的卡片图片
  • CardPunchResponseMessage,不包含任何内容,但表示卡片图像已复制到打孔缓冲区

我相信我必须知道我正在处理什么样的消息,所以我怀疑我不应该使用多态消息。我应该如何正确设计这个?

===== 编辑提出后续问题 =====

我试图找到一种方法来使用多态消息,而不必在某些时候识别它的子类。建议的方法是覆盖process()每个子类中的方法。这是我的(简化的)抽象 Message 和两个子类:

对于所有“入站”消息,每个线程都有一个队列。假设我的线程需要等待来自控制台的消息“恢复”,但同时应该接收和处理其他消息类型:

但现在呢?process() 的某些实现已将一些数据移动到某处,但最终我需要能够编写:

这基本上意味着找出“味精”属于哪个类。

我接近这一切都错了吗?我意识到“等待”在“事件驱动”模型中并不合适,但这是一个长期运行的后台工作者。也许使用 process() 的想法对于更改引导事件驱动线程的 FSM 的状态更有用?

0 投票
3 回答
133 浏览

c# - 我可以获得代码合同来警告我有关“非法”子类型的信息吗?

对不起,如果这个问题似乎太长了。在我问它之前,我需要说明它来自哪里。

设置:

给定以下不可变类型Rectangle

…从中派生一个类型似乎是完全合法的Square

…因为派生类可以确保它自己的不变量永远不会被违反。

但是一旦我变得Rectangle可变:

......我不应该再从中派生Square,因为Square不应该有独立的设置器Widthand Height

问题:

我可以用代码合同做什么,以便一旦我Square从可变Rectangle类派生它就会警告我违反合同?最好,Code Contracts 的静态分析已经在编译时给了我一个警告。

换句话说,我的目标是使用代码合同对以下规则进行编码:

  • WidthHeightaRectangle可以相互独立地改变。
  • WidthHeightaSquare不能相互独立地改变,这首先是没有意义的。

......并以这样一种方式进行,即每当这些规则“冲突”时,代码合同都会注意到。

到目前为止我所考虑的:

1. 添加一个不变量Rectangle

这种方法的问题在于,虽然不变量正确地说明了“宽度和高度不必相等,但它们可以相等”,但它是无效的,(1)因为它是重言式,(2)因为它比Width == Height派生类中的不变量限制更少Square。也许它甚至在代码契约看到它之前就被编译器优化掉了。

2. 给Rectanglesetter 添加后置条件:

这将禁止派生类简单Square地更新HeightWidth无论何时Width更改,反之亦然,它本身Square不会阻止我从Rectangle. 但这就是我的目标:让代码合同警告我Square不能从可变的Rectangle.

0 投票
1 回答
264 浏览

scala - 类型类和子类型

我有以下代码定义类型类。

现在,如果我有的话,我会toFoo(List(new A, new B)得到List("A", "A")而不是List("A", "B"). 如何确保使用该BtoFoo方法而不是AToFoo用于具有 type 的类B

0 投票
1 回答
5410 浏览

scala - 关于 Java 和 Scala 中的泛型

我对通用子类型感到困惑。

在 Java 中,如果 typeA是 的子类型,则B泛型类型是不变的。例如,不是 的子类型。C<A>C<B>ArrayList<Base>ArrayList<Derived>

C<A>但是,在 Scala 中,C<B>如果 typeAB. 那么Scala中泛型类的属性是什么,而Java中没有呢?

0 投票
0 回答
156 浏览

scala - Scala <:< 和 =:= 运算符是如何使用的,它们的 Predef 实现是如何工作的?

可能重复:
<:<、<%< 和 =:= 在 Scala 2.8 中是什么意思,它们在哪里记录?

显然 <:< 和 =:= 用于断言两种类型具有子类关系或相等。但是文档并不清楚它们是如何使用的,而且在谷歌中搜索它们几乎是不可能的,因为它们完全由符号组成。(还有一个原因是为什么这样的符号-goo 名称是一个坏主意。)

另外,它们在 Predef 中的实现是如何工作的?我很惊讶地发现它们不是内置的,因为我没有意识到 Scala 允许您创建以这种方式作用于类型的运算符——Scala 中的哪个功能可以让您这样做?Predef 中的实现是完全不透明的。这里有一些编译器魔法吗?

0 投票
4 回答
254 浏览

haskell - 在 Haskell 中使用数据类型

我已经开始了这个新问题,因为它是我之前问题的后续问题。

如果我有两种由相似构造函数组成的数据类型:

有没有办法我可以以某种方式将其表示为:

如果你能看到我在做什么 - 我正在尝试将 X | 分组 Y 转换为一种数据类型,然后可以被多种其他数据类型使用。我似乎无法让编译器允许这样做,或者如果允许,我无法与 X 或 Y 进行模式匹配,只能与 C??

我收到 C 已被多次声明的错误消息。

我想我也许可以使用类型,但它们不允许多种类型。

编辑

即使我声明了很长的路(如下所示),它仍然不会编译并说 X 和 Y 有多个声明:

0 投票
1 回答
1518 浏览

inheritance - Parametric Polymorphism vs Subtype polymorphism F#

What is the difference (if any) between these two F# type signatures?

and

Do they mean the same thing in this case?

msdn says the following about the (:>) Type Constraint

This would indicate that the two signatures are saying the same thing. So Functionally, how are they different?

0 投票
1 回答
248 浏览

scala - 通过继承更新不可变数据结构

我正在制作一个战略游戏,我尝试应用我学到的东西,尝试使用不可变的数据。在我的游戏中我有单位,这些单位可以有不同的特殊功能。例如,某些飞机可以隐藏自己。我搜索的是一种能够做某种事情的方法

无需复制粘贴:

在每个混合 Hidable 的案例类上。