【问题标题】:Why can't an interface have constructors and destructors?为什么接口不能有构造函数和析构函数?
【发布时间】:2011-11-05 18:58:42
【问题描述】:

我知道界面正在运行。当我开始在我的项目中编码时,我的脑海中就有了这个疑问。谁能澄清一下?

【问题讨论】:

  • 他们为什么要这样做?他们不是被创造和释放的人。实现实例是。

标签: c# interface constructor destructor


【解决方案1】:

接口是契约,而不是实现,因此无需构造或销毁它们。您只需构造和销毁可以实现接口的具体类型。

【讨论】:

    【解决方案2】:

    接口定义了一组方法,可以由一个或多个类实现。它的抽象定义了合同。

    接口不分配任何内存或实现任何方法

    接口没有任何初始化变量的功能。

    【讨论】:

      【解决方案3】:

      接口只是对象之间的契约。他们没有任何代码。给他们构造函数和析构函数就是给他们代码来运行。如果您需要在合约中进行初始化或清理,请添加 Initialize() 和 Uninitialize() 方法。

      【讨论】:

        【解决方案4】:

        因为接口不是可以构造或破坏的。这只是一个想法。一份合同。

        接口的构造是声明和定义它的行为。它们不是要实例化的对象。

        【讨论】:

          【解决方案5】:

          我同意接口是“合同”。就个人而言,我希望能够指定构造函数签名作为该合同的一部分。

          但见鬼,我喜欢像 Pascal 和 Ada 这样的语言,它们都竭尽全力指定正式的“接口”,与“实现”分开且不同。

          不管它有什么价值,从接口中排除构造函数——甚至是构造函数定义——有几个实际和理论上的原因。 C# 的参数与 Java 的参数基本相同。此链接具有指导意义:

          我非常同意这些观点:

          【讨论】:

            【解决方案6】:

            据我了解,您想知道为什么我们不能指定构造函数的签名以及其他对象的方法,例如

                interface IApp
                {
                     void App(int i, int j);
                }
                class App : IApp
                {
                     // You want constructor to be only with 2 parameters
                     public void App(int i, int j){ }
                }
            

            不能这样做,因为首先,所有接口方法都应该实现为公共,但构造函数可以设置为私有,其次,方法 void App(..) 将是构造函数仅适用于 App 类,对于另一个类,它将是另一种方法。

            所以一般来说,如果要指定参数已知的构造函数,尽量使用抽象基类。

            【讨论】:

            • 次要,但也可以将其他方法设置为私有。当他们实现一个接口时,他们必须像你说的那样是公共的,但是构造函数在他们可以拥有的可见性方面确实没有任何不同。
            • 1) 正如@AdamLear 所说,每个方法都可以是公共的或私有的。 2)即使使用抽象类,你也可以在派生类中有私有构造函数,那么你的意思是什么? 3) 接口“IApp”中的构造函数应该是“IApp(int i, int j)”,而不是“App(int i, int j)”,否则实现IApp的App2应该包含一个名为“App”的构造函数(? ?)。投反对票。
            【解决方案7】:

            可以定义一个名称与接口类似的静态类,其中包含工厂方法或属性以生成实现接口的类实例。这方面的示例包括 Enumerable.Empty 和 Comparer.Default。我个人认为,如果有一种方法可以指定接口名称应该可用于引用静态成员(通过具有相同名称的接口和静态类,能够在接口中包含静态成员,能够将静态类指定为与接口“关联”或其他)。不幸的是,我不知道任何 .net 语言都有这样的功能。最好的办法是使用具有相似名称的静态类(如 IEnumerable/Enumerable 和 IComparer/Comparer)。

            顺便说一句,如果接口可以包含静态数据,那么一个不错的附加功能就是让它们包含自己的扩展方法。例如:

            void SetBounds(int x, int y, int width, int height, BoundsSpecified specified); static void SetBounds(int x, int y, int width, int height) { It.SetBounds(x, y, width, height, BoundsSpecified.All); } 静态无效 SetSize(整数宽度,整数高度) { It.SetBounds(0, 0, 宽度, 高度, BoundsSpecified.Size); }

            允许接口向其用户公开许多常用函数的重载版本,而无需所有实现都包含实现它们所需的样板代码。

            【讨论】:

              【解决方案8】:

              我也多次问过自己这个问题,现在似乎想到了一种解释:

              接口契约描述**做什么**对象,而不是**如何**做。构造函数可能与 How 有更多的关系,所以这就是为什么我们不能让它成为合同的一部分。

              接口的客户期望接收一个已经构造好的对象,所以他们不关心构造函数的签名。至于将创建该对象的代码,它已经知道要创建什么具体对象,因此它知道构造函数签名。

              【讨论】:

                【解决方案9】:

                我采用了另一种方法,即“如果……会怎样”的问题。这是我的结论(from my blog):

                第一个:Given 是一个接口 IApp,它定义了一个构造函数“ctor(int)”。

                第二个:定义了一个类 MyApp 并实现了 IApp。

                ==> MyApp 类现在有一个来自 IApp 的构造函数“ctor(int)”

                第三个:给定的是第二个接口ICoolApp,它定义了一个构造函数“ctor(string)”

                4th:MyApp 类实现了ICoolApp。 ==> Class MyApp 现在有两个构造函数“ctor(int)”和“ctor(string)”。到目前为止一切顺利。

                即使定义了具有相同签名的构造函数,显式实现也可以定义两种不同的方式来创建 MyApp 类(因为它已经与方法一起使用)。

                5th:创建了一个新的 MyApp 实例,调用“new MyClass(int)”。这个新实例是一个 IApp 和一个 ICoolApp,因为它实现了这两个接口。没问题吧?

                ==> 错了! MyApp 类有两个构造函数,但实例是通过调用 IApp 的构造函数创建的。没有调用实现 ICoolApp 创建对象方式的构造函数“ctor(string)”。

                作为结论,MyApp的实例既是IApp又是ICoolApp,但是实例的创建只履行了一个契约,即IApp的契约。并且由于签名不同,在实例创建期间不可能同时履行两个合同,尽管 MyApp 声称尊重/实施两个合同。

                【讨论】:

                • 我不太明白你的意思。 5号左右。我使用“new MyApp(int)”创建了一个 MyApp 实例。现在我有一个实现这两个接口的 MyApp 实例。 “未调用构造函数'ctor(string)'”是什么意思?好的,它没有被调用,因为该实例是使用另一个 ctor 创建的。所以?重点是什么?有什么问题?如果你有一个类从两个不同的接口实现两种方法,调用一个方法并不意味着对象不再遵守另一个接口的约定。
                • @MassimilianoKraus 他的观点是,两个接口都对如何创建对象有一个“期望”。由于实现了这两个接口,因此不可能同时满足这两个接口,除非由实现这两个构造函数的人负责。在我看来,这实际上是这里最好的解释。虽然有点杂乱无章。
                猜你喜欢
                • 2017-06-04
                • 2017-12-21
                • 2022-12-11
                • 2013-07-07
                • 1970-01-01
                • 1970-01-01
                • 2020-08-24
                • 2016-02-17
                • 1970-01-01
                相关资源
                最近更新 更多