问题标签 [constructor-chaining]
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.
syntax - Boo 构造函数链接
在 C# 中,当我想将构造函数链接在一起时,我会这样做......
Boo 中的等效语法是什么?
c# - 这是使用构造函数链接的好方法还是坏方法?(...允许测试)
我在这里链接我的类构造函数的动机是,我有一个默认构造函数供我的应用程序主流使用,还有一个允许我注入模拟和存根。
在 ":this(...)" 调用和从默认构造函数调用参数化构造函数中的“新”事物看起来有点丑陋,我想知道其他人会在这里做什么?
(仅供参考-> SystemWrapper)
c# - : this() 作为构造函数
我试图更好地理解一般实践......特别是在构造函数中派生 this() 。我知道它的代码较少,但我认为它的可读性较差。这样做是常见的/好的做法吗?还是编写第二个专门处理它的构造函数更好?
或者
任何投入将不胜感激
delphi - Delphi:如何隐藏祖先构造函数?
更新:用一个更简单的例子解决了这个问题,最初接受的答案没有回答
给定以下类及其祖先:
现在TCellPhone
有 3 个可见的构造函数:
- 杯子:整数
- 杯子:整数;茶壶:串
- 茶壶:string = ''
我该怎么做才能TCellPhone
使祖先构造函数(Teapot: string = ''
)不可见,只留下声明的构造函数:
- 杯子:整数
- 杯子:整数;茶壶:串
注意:通常拥有后代构造函数的简单行为会隐藏祖先:
- 杯子:整数
如果您想同时保留祖先构造函数和后代,您可以将后代标记为
overload
:
- 杯子:整数
- 茶壶:string = ''
在这个问题的示例代码中,Delphi 弄错了我的overload
关键字:
认为:
- 我想用祖先重载我的构造函数,
- 当我真的想用兄弟姐妹重载它时
我如何隐藏祖先构造函数?
注意:使用当前定义的 Delphi 语言可能无法隐藏祖先的非虚拟构造函数。“不可能”是一个有效的答案。
尝试回答(失败)
我尝试reintroduce
用(回退到我随机添加关键字的模式直到它起作用)标记后代构造函数:
但这不起作用,所有三个构造函数仍然可见。:(
原始问题
我有一个对象,该对象来自一个具有构造函数不想看到的类:
注意:这是一个假设的例子。与现实世界一样,在不破坏现有代码的情况下无法更改祖先对象。
现在,当有人使用时,TiPhone
我什至不希望他们能够从以下位置看到构造函数TEniac
:
更糟糕的是:如果他们调用那个构造函数,他们完全想念我的构造函数,以及在这两者之间完成的所有事情。调用错误的构造函数很容易,它们都在 IDE 代码完成中可见,并将编译:
他们得到一个完全无效的对象。
我可以更改TCellPhone
为在这些构造函数中引发异常:
但是开发人员不会意识到他们调用了错误的构造函数,直到客户有一天发现错误并对我们处以数十亿美元的罚款。事实上,我试图找到我调用错误构造函数的所有地方 - 但我不知道如何让 Delphi 告诉我!
delphi - Delphi:理解构造函数
我想了解
- 虚拟的
- 覆盖
- 超载
- 重新引入
当应用于对象构造函数时。每次我随机添加关键字直到编译器关闭 - 并且(在使用 Delphi 开发 12 年后)我宁愿知道我在做什么,而不是随机尝试。
给定一组假设的对象:
我希望他们的行为方式从声明中可能很明显,但是:
TComputer
有简单的构造函数,后代可以覆盖它TCellPhone
有一个备用构造函数,后代可以覆盖它TiPhone
覆盖两个构造函数,调用每个构造函数的继承版本
现在该代码无法编译。我想了解为什么它不起作用。我也想了解重写构造函数的正确方法。或者也许你永远无法覆盖构造函数?或者也许重写构造函数是完全可以接受的?也许你永远不应该有多个构造函数,也许拥有多个构造函数是完全可以接受的。
我想了解原因。修复它就很明显了。
也可以看看
编辑:我也希望对virtual
, override
, overload
,的顺序进行一些推理reintroduce
。因为在尝试所有关键字组合时,组合的数量会爆炸式增长:
- 虚拟的; 超载;
- 虚拟的; 覆盖;
- 覆盖;超载;
- 覆盖;虚拟的;
- 虚拟的; 覆盖;超载;
- 虚拟的; 超载; 覆盖;
- 超载; 虚拟的; 覆盖;
- 覆盖;虚拟的; 超载;
- 覆盖;超载; 虚拟的;
- 超载; 覆盖;虚拟的;
- ETC
编辑2:我想我们应该从“给定的对象层次结构是否可能? ”如果不是,为什么不呢?例如,拥有来自祖先的构造函数是根本不正确的吗?
我希望TCellPhone
现在有两个构造函数。但我无法在 Delphi 中找到关键字组合,使其认为这是一件有效的事情。我认为我可以在这里有两个构造函数从根本上是错误的TCellPhone
吗?
注意:这条线以下的所有内容并不是回答问题所必需的——但它确实有助于解释我的想法。也许您可以根据我的思维过程看到,我遗漏了哪些让一切变得清晰的基本部分。
现在这些声明无法编译:
所以首先我会尝试修复TCellPhone
。我将从随机添加overload
关键字开始(我知道我不想要reintroduce
,因为这会隐藏另一个我不想要的构造函数):
但这失败了:Field definition not allowed after methods or properties
.
我从经验中知道,即使我在方法或属性之后没有字段,如果我颠倒virtual
andoverload
关键字的顺序:Delphi 会闭嘴:
但我仍然得到错误:
方法“创建”隐藏基本类型“TComputer”的虚拟方法
所以我尝试删除这两个关键字:
但我仍然得到错误:
方法“创建”隐藏基本类型“TComputer”的虚拟方法
所以我辞职现在尝试reintroduce
:
现在 TCellPhone 编译了,但它让 TiPhone 的情况变得更糟:
两者都抱怨我无法覆盖它们,所以我删除了override
关键字:
但是现在第二次创建说它必须标记为重载,我这样做(实际上我会将两者都标记为重载,因为我知道如果我不这样做会发生什么):
该部分的一切都很好interface
。不幸的是,我的实现不起作用。我的 TiPhone 单参数构造函数不能调用继承的构造函数:
delphi - Delphi:如何为后代添加不同的构造函数?
更新:我最初的例子有点复杂。这是一个简单的 8 行示例,它在一个代码块中解释了所有内容。以下不编译给出警告:
注意:这个问题是我正在进行的关于 Delphi 构造函数的微妙之处的系列问题的第 3 部分
原始问题
如何将构造函数添加到现有类?
让我们举一个假设的例子(即我在 SO 编辑器中输入的例子,所以它可能编译也可能不编译):
进一步假设正常使用TXHTMLStream
涉及执行大量重复代码后才能使用:
假设我想创建一个简化所有样板设置代码的构造函数:
这将对象的使用简化为:
除了现在 Delphi 抱怨我的新构造函数隐藏了旧构造函数。
方法“创建”隐藏基本类型“TXMLStream”的虚拟方法
我当然不是有意隐藏祖先的创造——我想要两者。
如何将构造函数(具有不同的签名)添加到后代类,同时保留祖先构造函数以便它仍然可以使用?
delphi - Delphi:什么时候重新引入隐藏祖先,什么时候显示它们?
今天最近在 Stackoverflow 上我了解到:
我一直在努力理解这一切,所以这是另一个非常具体的问题,支持我处理构造函数的主要问题。
更新:替换了整个问题:
构造 TCellPhone 时,可以使用 3 个构造函数:
- 杯子:整数
- 杯子:整数;茶壶:串
- [茶壶:字符串='']
问:为什么constructor(Teapot: string='')
不被隐藏?
现在我添加了第三个后代:
构造TiPhone
四个构造函数时可用:
- 杯子:整数
- 杯子:整数
- 杯子:整数;茶壶:串
- [茶壶:字符串='']
为什么有四个构造函数?我覆盖了现有的三个之一。编辑:这可能是代码洞察力中的一个错误,它向我展示了四个 - 但是当两个相同时我怎么可能调用。
再次使用原始代码:
已知TCellPhone
有三个构造函数:
- 杯子:整数
- 杯子:整数;茶壶:串
- [茶壶:字符串='']
如何更改声明TCellPhone
以隐藏祖先构造函数?例如,这样:
将只有两个构造函数:
- 杯子:整数
- 杯子:整数;茶壶:串
现在用于reintroduce
隐藏非虚拟祖先的情况。在前一种情况下TiPhone
,有四个构造函数(理想情况下只有两个 - 以TComputer
某种方式隐藏其祖先)。但即使我无法修复TComputer
,我也可以TiPhone
改为只有一个:
现在TiPhone
只有一个构造函数:
- 杯子:整数
Reintroduce 通常只用于抑制隐藏虚拟祖先的警告。在这种情况下:
不是虚拟的——但我仍然可以使用 reintroduce 来隐藏它。
但是现在,如果我添加另一个重载到TiPhone
:
然后突然(以前隐藏的)祖先回来了:
- TiPhone.创建(7);
- TiPhone.Create('粉红色');
- TiPhone.Create(7, '粉红色');
- TiPhone.Create();
如您所见,我正在努力理解
- 当某事被隐藏时
- 如何隐藏某事
- 当显示某些东西时
- 如何显示某事
delphi - Delphi:重写的虚拟构造函数后代未被重载调用
我关于 Delphi 构造函数的系列问题中的另一个问题。
我有一个具有虚拟构造函数的基类:
构造函数在有人需要调用的时候是虚拟的
构造函数overridden
在后代中:
WhereTCellPhone
和TiPhone
后代每个都有机会进行自己的初始化(为了便于阅读,不包括成员)。
但是现在我向某个祖先添加了一个重载的构造函数:
TCellPhone 中的备用构造函数调用另一个虚拟构造函数,因此它始终获得正确的覆盖行为:
问题是永远不会调用后代的、被覆盖的构造函数。调用的实际堆栈跟踪链是:
对 的同级调用TCellPhone.Create(int)
,它是虚拟的,应该在 中调用后代的、被覆盖的方法TiPhone
:
所以似乎使用兄弟虚拟构造函数的尝试是 Delphi 不能按预期工作。
那么一个构造函数使用另一个构造函数是不是一个坏主意?重载构造函数中的代码是彼此复制粘贴版本的设计意图吗?
我注意到在 .NET 中,一些构造函数相互链接:
这似乎只是一个问题,如果:
- 构造函数是虚拟的
- 你重载了构造函数
规则是不能让一个构造函数重载另一个构造函数吗?
delphi - 了解构造函数可见性
这是两个简单的类,最初都没有关键字(virtual、overload、override、reintroduce):
我将把上述这些定义表示为略短:
并且在构造时TCellPhone
只有一个构造函数 ( int
, string
) - 因为祖先构造函数已被隐藏。我将指出以下的可见构造函数TCellPhone
:
- 茶壶:整数;句柄:字符串
现在对于这个问题,前 3 种情况是有道理的,第 4 种情况没有:
1.祖先构造函数被后代隐藏:
Teapot: Integer; Handle: string
这是有道理的,祖先构造函数是隐藏的,因为我已经声明了一个新的构造函数。
2.祖先虚构造函数被后代隐藏:
Teapot: Integer; Handle: string
这是有道理的,祖先构造函数是隐藏的,因为我已经声明了一个新的构造函数。
注意:因为祖先是虚拟的:Delphi 会警告你隐藏了虚拟祖先(在前面的隐藏静态构造函数的例子中:没人关心,所以没有警告)。可以通过添加reintroduce来抑制警告(意思是“是的,是的,我正在隐藏一个虚拟构造函数。我 打算这样做。”):
3. 由于重载,祖先构造函数没有隐藏在后代中:
Teapot: Integer; Handle: string
Teapot: Integer
这是有道理的,因为后代构造函数是祖先的重载,所以两者都被允许存在。祖先构造函数没有被隐藏。
4.虚拟祖先构造函数没有隐藏在后代中,因为重载 -但仍然收到警告:
这是没有意义的情况:
Teapot: Integer; Handle: string
Teapot: Integer
方法“创建”隐藏基本类型“TComputer”的虚拟方法
这没什么意义。不仅祖先不隐藏,后代超载;它甚至不应该抱怨。
是什么赋予了?
javascript - JavaScript 中的链式构造函数
我正在尝试在 JavaScript 中实现某种类层次结构。我想我理解了原型链,但我仍然需要理清构造函数链。按照大卫弗拉纳根的权威指南,我写了
哪里BaseClass()
是我用 C++ 编写的本机函数(我正在使用QtScript)。我的问题是,然后,BaseClass()
它被称为函数,而不是构造函数。
我可以编写代码BaseClass()
以始终充当构造函数,但是它被调用了。但我担心有一天我的一个用户可能会忘记new
并只是写
在这种情况下,我BaseClass()
想做一些比初始化全局对象更明智的事情。例如:
但是随后构造函数链接失败!
有没有办法可以链接构造函数并BaseClass()
实际上被称为构造函数?还是我应该教育我的用户永远不要忘记new
?现在我很想通过以下方式替换上面的测试:
但我想知道是否有更清洁的方法来处理这个问题。
谢谢!