问题标签 [polymorphism]

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 投票
19 回答
795675 浏览

c++ - 何时使用虚拟析构函数?

我对大多数理论都有扎实的理解,OOP但让我很困惑的一件事是虚拟析构函数。

我认为析构函数总是被调用,不管是什么,对于链中的每个对象。

你打算什么时候把它们变成虚拟的,为什么?

0 投票
7 回答
2669 浏览

c++ - 在 C++ 中复制一个未知的具体类型

假设我们有以下类层次结构:

给定一个Base*可以指向aDerived1Derived2对象的a,鉴于它的具体类型未知,我如何制作实际对象的副本。我想过定义复制构造函数,但我认为如果不知道所涉及的实际类型,这是不可能的。我能想到的唯一解决方案是为层次结构中的每种类型定义一个clone()方法。有人能想到更优雅的东西吗?

0 投票
4 回答
1707 浏览

c# - 是否有可能避免沮丧?

我有一些逻辑,它定义和使用一些用户定义的类型,比如:

逻辑在使用类型进行计算(例如定位每个Word实例)之后,间接使用一些SystemAPI,例如通过调用Canvass.draw方法。

我想让这个逻辑独立于System.Drawing命名空间:主要是为了帮助进行单元测试(我认为单元测试的输出会更容易验证该draw方法是否绘制到真实System.Drawing.Graphics实例之外的东西)。

为了消除逻辑对命名空间的依赖System.Drawing,我想我会声明一些新接口作为System.Drawing类型的占位符,例如:

如果我这样做了,那么不同的程序集可能有不同的IMyFontandIMyGraphics接口实现,例如......

...但是,如上图所示,实现将需要向下转换。

我的问题是,有没有一种方法可以做到这一点而无需在实施过程中感到沮丧?Word通过“这个”,我的意思是“定义像并且Canvass不依赖于特定具体类型的UDT System”?

另一种选择是抽象 UDT ...

...但这也需要在子类的实现中进行向下转换。

我也想过使用双重调度习惯,但这取决于命名 API 中的各种子类。

或者,如果没有接口或子类,有没有使用委托的方法?


- 编辑: -

有两种可能的答案。

一个答案是使用泛型,正如下面“兰蒂斯爵士”的回答所建议的那样,以及 John Skeet 链接到的博客文章所建议的那样。我怀疑这在大多数情况下都可以正常工作。从我的角度来看,不利的一面是它意味着TFont作为模板参数引入:它不仅是一个类Word(包含一个Font实例),它需要成为一个泛型类(如WordT<TFont>)......这也是任何包含WordT<TFont>(eg Paragraph) 的类现在也需要成为具有TFont参数 (eg ParagraphT<TFont>) 的泛型。最终,程序集中的几乎每个类都变成了泛型类。这确实保留了类型安全性并避免了向下转换的需要......但是它有点难看,并且扰乱了封装的错觉(“字体”是不透明的实现细节的错觉)。

另一个答案是在用户类中使用地图或字典。而不是Font在可重用库中,而不是抽象接口,定义一个“句柄”类,如:

然后,不要从 向下转换,而是FontHandle保留一个将值Dictionary<int, Font>映射到实例的实例。FontHandleFont

0 投票
5 回答
33070 浏览

java - Java 中的继承 - “找不到符号构造函数”

我正在研究一个从另一个类继承的类,但我收到一个编译器错误,提示“找不到符号构造函数 Account()”。基本上,我要做的是创建一个从 Account 扩展的类 InvestmentAccount - Account 旨在通过提取/存入资金的方法保持余额,而 InvestmentAccount 类似,但余额存储在股票中,股价决定如何给定特定数量的资金,许多股票被存入或取出。这是子类 InvestmentAccount 的前几行(编译器指出问题的地方):

Person 类保存在另一个文件 (Person.java) 中。现在这里是超类 Account 的前几行:

为什么编译器不只是从 Account 类中读取 Account 的符号构造函数?或者我是否需要在 InvestmentAccount 中为 Account 定义一个新的构造函数,告诉它继承所有内容?

谢谢

0 投票
5 回答
14117 浏览

language-agnostic - 多态性如何替换循环内的 if-else 语句?

多态性如何替换循环内的 if-else 语句或 Switch?特别是它总是可以替换 if-else 吗?我在循环中使用的大多数 if-then 都是算术比较。这个问题就是从这个问题衍生出来的。

这将如何与多态性一起工作?
注意:我是用 Java 编写的,但对任何 OOL 都对此感兴趣。

0 投票
11 回答
51610 浏览

c - 如何在 C 中模拟 OO 风格的多态性?

有没有办法用C编程语言编写类似 OO 的代码?


也可以看看:

通过搜索“[c] oo”找到。

0 投票
5 回答
329 浏览

language-agnostic - 使用 TDD 开发接口

我是 TDD 的忠实拥护者,并且这些天在我的绝大多数开发中都使用它。但是,我经常遇到的一种情况,并且从未找到我认为是“好的”答案的情况,类似于以下(人为的)示例。

假设我有一个像这样的接口(用 Java 编写,但实际上,这适用于任何 OO 语言):

现在,假设我想创建这个接口的三个实现。我们称它们DijkstraPathFinder为 、DepthFirstPathFinderAStarPathFinder

问题是,如何使用 TDD 开发这三个实现?它们的公共接口将是相同的,并且大概我会为每个接口编写相同的测试,因为 getShortestPath() 和 getShortestPathLength() 的结果在所有三个实现中应该是一致的。

我的选择似乎是:

  1. PathFinder当我编写第一个实现时,编写一组测试。然后“盲目”编写其他两个实现并确保它们通过PathFinder测试。这似乎不对,因为我没有使用 TDD 来开发后两个实现类。

  2. 以测试优先的方式开发每个实现类。这似乎不对,因为我将为每个班级编写相同的测试。

  3. 结合上述两种技术;现在我有一组针对接口的测试和一组针对每个实现类的测试,这很好,但是测试都是一样的,这不是很好。

这似乎是一种相当普遍的情况,尤其是在实现策略模式时,当然实现之间的差异可能不仅仅是时间复杂度。其他人如何处理这种情况?是否有针对我不知道的接口进行测试优先开发的模式?

0 投票
2 回答
2003 浏览

c# - 使用接口组合的奇怪的接口多态性

在我正在处理的项目中,我最终得到了类似以下代码的内容。我认为我被允许这样做真的很奇怪,但现在我开始想知道我最有可能的建筑失误导致我这样做。

我对你的问题是:

  • 这到底叫什么?
  • 这在现实世界中有什么用途?
  • 为什么会有人想要这样做?

这是我的接口:

这是我的具体课程:

我的及格测试:

0 投票
4 回答
317 浏览

.net - 是否可以通过覆盖将访问器添加到 .NET 中的属性?

有可能做这样的事情吗?

也就是说,基类提供了一个只有 GET 访问器的虚拟属性,但子类覆盖了 GET 并还提供了一个 SET。

当前示例无法编译,但也许我在这里遗漏了一些东西。

补充:为了澄清,不,我不想用 new 重新定义。我想添加一个新的访问器。我知道它不在基类中,所以它不能被覆盖。好的,让我试着解释一下没有语法糖的情况:

0 投票
2 回答
2109 浏览

c++ - 使用 SWIG 跨 C++ 和 Ruby 的多态性

我使用 SWIG 将 Ruby 脚本包装在 C++ 库周围。在 Ruby 中,我可以从 C++ 类继承,但不能以多态方式将结果指针传递给 C++ 函数。

这是一个具体的例子。SWIG 接口文件定义了具有虚函数 sound() 的基类 Animal:

请注意,我将 SWIG 导向器用于跨语言多态性,但这似乎不起作用。Ruby 脚本如下所示:

脚本中的最后一行产生了这个错误:

所以不知何故 SWIG 不允许我将 Ruby 对象视为指向动物的指针。有任何想法吗?