Why are we not allowed to specify a constructor in an interface?
Possible Duplicate:
Interface defining a constructor signature?
我知道你不能在.NET的接口中指定构造函数,但是为什么我们不能呢?
对于我当前的项目来说,能够指定"引擎"必须与构造函数一起传入是非常有用的,但是由于我不能这样做,我必须对类使用XML注释。
型
因为接口描述了行为。构造函数不是行为。如何构建对象是一个实现细节。
- 我认为这给实现细节赋予了太多的意义:NET中的构造函数实际上只是一个在创建对象(在内存中分配)后立即被调用的方法。也没有理由不能将其定义为行为。当然,实现也可以自由地声明其他构造函数,就像它们可以重载实现接口的方法一样。接口中的构造函数是一个很少使用的特性,但不是一个无用的特性。
- 我认为问题的关键在于:既然它是以这种方式构建的,那么最佳实践是什么?所以我想答案是:通过使用抽象类,正如这个答案所说:stackoverflow.com/a/2804067/1181162
型
如何调用构造函数?使用接口时,通常会传递接口的实例(或者更确切地说,是引用)。还要记住,如果一个类实现了接口,则派生类继承了该接口,但可能没有相同的构造函数集。
现在,我可以看到使用我所称的静态接口来指定构造函数和其他基本上静态的成员,以便在泛型方法中使用。有关详细信息,请参阅我关于该想法的博客文章。
- +1我认为这将是对.NET的一个很好的添加,并且我已经对关联的Connect反馈项进行了升级:connect.microsoft.com/VisualStudio/Feedback/Details/412848/…
- 我可以想到接口的三个类特性:(1)方法或属性的默认实现(请注意,继承的接口不能重写基接口);(2)允许同一标识符有效地与接口和静态类双重使用;(3)定义在对接口调用"new"时要使用的静态方法。接口。注意2和3是句法上的糖分,但我认为它们会使一些东西更干净。如果.NET支持1,接口可以添加新的方法或属性,而不破坏现有的实现。
- @Supercat:是的,我也考虑过1,我相信MS也是。有一次万斯·莫里森的采访,他谈到了这件事。
- 我很想知道正在做的是什么,1;我还想知道微软是否正在添加任何好的方法来清理IDisposables,当构造函数抛出异常,或(对于vb)如果有一种方法可以自动杀死所有的事件订阅。我看到了一些新功能旧讨论的链接;您有什么最新的吗?
- @超级跑车:不知道,恐怕。我没听说过这件事。
- @你能解释一下你所说的静态接口是什么意思吗?听起来你的意思是一个不能被实例化的接口,但是接口根本不能被实例化,所以没有任何意义。
- @金弗里托:你读过我链接到的博客文章吗?
- @我读过,但老实说,我读了之后比进去的时候更困惑。
- @金弗里托:在这种情况下,我建议你忽略第二段。我怀疑再次解释它(这不仅仅是一个评论)会有所帮助。
型
不,由于已发布的原因,不能在接口上有构造函数。但是在抽象类上可以。例如,假设您有这个基类。
1 2 3 4 5 6 7 8 9 10 11
| public abstract class ClassOne
{
protected int _x;
protected string _s;
public ClassOne(int x, string s)
{
_x = x;
_s = s;
}
} |
注意,没有不带参数的构造函数(默认构造函数),这意味着从ClassOne继承的任何类都必须调用具有2个参数的构造函数。
所以这是无效的,不会编译。
1 2 3 4 5
| public class ClassTwo : ClassOne
{
public ClassTwo()
{ }
} |
号
但是,这是有效的并将编译。
1 2 3 4 5
| public class ClassTwo : ClassOne
{
public ClassTwo(int x, string s) : base(x, s)
{ }
} |
我想在这里指出,在C中,您只能从一个基类继承。这意味着,这可能不是针对特定情况的正确解决方案,而是需要考虑的问题。
托尼。
- 由于类不能继承构造函数,我认为这只是一个局部解决方案,因为它要求子类以特殊的方式实现其构造函数调用,但不能保证子类具有相同签名的构造函数。
型
在已经发布的所有其他原因中,还要记住,A类可以轻松实现几个接口;那么应该使用哪个构造函数呢?
- 对于实现具有相同签名的接口方法,有一种非常好的语法可以用于构造函数。
- 我不确定我是否理解你的观点(也许我没有):我的意思是,类A可以实现没有参数的构造函数的接口ialpha,具有一个参数的构造函数ibeta,以及具有两个参数的构造函数igamma:哪个构造函数应该类A实现?
- 啊,这是唯一对我有意义的答案。所有不能实例化接口的参数都让我问"那又怎样?"接口的要点是声明此类函数和此类函数集必须在假定要实现接口的任何类中实现。这样的类还必须实现一个采用这组特殊参数的构造函数,这听起来很合理。但是冲突的构造函数参数,现在出现了一个问题。
- 完全同意杰伊的观点。虽然我认为通过接口强制构造函数签名不是一个荒谬的想法,但是需要考虑更多的问题。
- 对于.NET来说,简单地禁止具有相同方法签名的接口的实现并不难。事实上,不是这样吗?如果不是的话,我认为它应该不考虑构造函数的问题。
型
其他答案已经指出了为什么在接口上有一个构造函数声明是没有意义的。但从你的问题来看,我猜你可能在寻找抽象的工厂模式。
基于您的问题给出一个示例:您说您希望以某种方式声明必须将"引擎"传递给构造函数。您可以通过为这样的构建服务声明一个单独的接口来实现这一点:
1 2 3 4
| public interface IGadgetFactory
{
IGadget CreateGadget(Engine engine);
} |
。
任何必须创建IGadget实例的代码都可以使用IGadgetFactory实例,而不是直接调用任何构造函数。
型
除了这里给出的其他解释之外,您还必须发明一种新的语法来调用它们,因为如果您在该行的范围内有两个或多个实现:
调用哪个实现?
- 如果我设计一种语言,我将允许一个接口命名一个要使用的静态方法,因此上面的语句将等价于例如Dim X As IDoStuff = IDoStuff_Creator.CreateNew();。
型
因为你不能实例化一个接口,所以一个构造是没有意义的。