为什么接口不能有构造函数和析构函数?
我知道该界面正在运行。当我开始在项目中编码时,我心中产生了这个疑问。谁能澄清一下吗?
I know the interface is working. When I started coding in my project, I got this doubt in my mind. Can anyone clarify ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
我采用了另一种方法,即“如果……会怎样”的问题。这是我的结论(来自我的博客):
第一个:给定的是一个接口 IApp,它定义了一个构造函数“ctor(int)”。
第二:定义类MyApp并实现IApp。
==> MyApp 类现在有一个来自 IApp 的构造函数“ctor(int)”。
第三:给定的是第二个接口 ICoolApp,它定义了构造函数“ctor(string)”。
第四:MyApp 类实现了 ICoolApp。
==> MyApp 类现在有两个构造函数“ctor(int)”和“ctor(string)”。到目前为止,一切都很好。
即使存在定义了相同签名的构造函数,显式实现也可以定义两种不同的方式来创建 MyApp 类(因为它已经可以使用方法)。
第五:调用“new MyClass(int)”创建 MyApp 的新实例。这个新实例是 IApp 和 ICoolApp,因为它实现了这两个接口。没问题吧?
==>错误的! MyApp 类有两个构造函数,但实例是通过调用 IApp 的构造函数创建的。未调用用于实现 ICoolApp 创建对象的方式的构造函数“ctor(string)”。
综上所述,MyApp 的实例既是 IApp,又是 ICoolApp,但实例的创建只履行了一个契约,即 IApp 的契约。而且由于签名不同,尽管 MyApp 声称尊重/实现这两个合同,但在实例创建过程中不可能同时履行这两个合同。
I did another approach, the "what if..." question. And this is my conclusion (from my blog):
1st: Given is an interface IApp which defines a constructor "ctor(int)".
2nd: A class MyApp is defined and implements IApp.
==> Class MyApp now has a constructor "ctor(int)" from IApp
3rd: Given is a second interface ICoolApp which defines a constructor "ctor(string)"
4th: Class MyApp implements ICoolApp.
==> Class MyApp has now two constructors "ctor(int)" and "ctor(string)". So far so good.
Even if there would be constructors with the same signature defined, an explicit implementation can define two different ways to create the class MyApp (as it works with methods already).
5th: A new instance of MyApp ist created calling "new MyClass(int)". This new instance is an IApp and and ICoolApp because it implements both interfaces. No problems, right?
==> Wrong! The class MyApp has two constructors, but the instance was created by calling IApp's constructor. The constructor "ctor(string)" to fulfill ICoolApp's way of creating objects was not called.
As a conclusion, the instance of MyApp is both, an IApp and ICoolApp, but the creation of the instance only fulfilled one contract, the contract of IApp. And because of different signatures, it is not possible to fulfill both contracts at the same time during instance creation, although MyApp claims to respect/implement both contract.
接口定义了一组可以由一个或多个类实现的方法。它的抽象定义了合同。
接口不分配任何内存或实现任何方法
接口不具有任何初始化变量的功能。
Interface defines set of the methods will can be implemented by the one or more classes. Its abstact from that defines the contract.
Interface doesnt allocate any memory or implement any methods
Interface doesnt have any functionality to initialize the variable in that.
接口只是对象之间的契约。他们没有任何代码。给它们构造函数和析构函数就等于给它们运行代码。如果您需要在合约中进行初始化或清理,请添加 Initialize() 和 Uninitialize() 方法。
Interfaces are just contracts between objects. They don't have any code. Giving them constructors and destructors would be giving them code to run. If you need initialization or cleanup in your contract, you add an Initialize() and Uninitialize() method.
因为接口不需要构造或破坏。这只是一个想法。一份合同。
接口的构造是声明和接口的行为。定义它。它们不是要实例化的对象。
Because an interface is nothing to construct or destruct. It is simply an idea. A contract.
The construction of an interface is the act of declaring & defining it. They are not objects to be instantiated.
我同意接口是一个“契约”。就我个人而言,我希望能够将构造函数签名指定为该合同的一部分。
但哎呀,我喜欢像 Pascal 和 Ada 这样的语言,它们都竭尽全力指定一个正式的“接口”,与“实现”分开且不同。
无论其价值如何,从接口中排除构造函数(甚至构造函数定义)有几个实际和理论原因。 C# 的参数与 Java 的参数基本相同。此链接很有指导意义:
我非常喜欢同意这些观点:
I agree that interfaces are a "contract". And personally, I'd like to be able to specify constructor signatures as part of that contract.
But heck, I like languages like Pascal and Ada, which both go to great lengths to specify a formal "interface", separate and distinct from the "implementation".
For whatever it's worth, there are several practical as well as theoretical reasons for excluding constructors - or even constructor definitions - from interfaces. The arguments are basically the same for C# as they are for Java. This link is instructive:
I pretty much agree with these sentiments:
可以定义一个静态类,其名称类似于接口,其中包含工厂方法或属性来生成实现该接口的类实例。其示例包括 Enumerable.Empty 和 Comparer.Default。我个人认为,如果有一种方法可以指定接口名称应该可用于引用静态成员(通过具有同名的接口和静态类,能够在接口中包含静态成员,能够指定一个静态类与接口“关联”,或者其他)。不幸的是,我不知道任何 .net 语言都有这样的功能;最好的方法是使用具有相似名称的静态类(如 IEnumerable/Enumerable 和 IComparer/Comparer)。
顺便说一句,如果接口可以包含静态,那么一个很好的奖励功能就是让它们包含自己的扩展方法。例如:
允许接口向用户公开公共函数的许多重载版本,而不要求所有实现都包含实现它们所需的样板代码。
It is possible to define a static class, with a name similar to the interface, that includes factory methods or properties to generate class instances that implement the interface. Examples of this include Enumerable<T>.Empty and Comparer<T>.Default. I personally think it would be helpful if there were a means of specifying that an interface name should be usable to refer to static members (either by having an interface and static class of the same name, being able to include static members within an interface, being able to designate a static class as being 'associated' with an interfafce, or whatever). Unfortunately, I am unaware of such a facility in any .net language; the best one can do is use a static class with a similar name (as with IEnumerable/Enumerable and IComparer/Comparer).
Incidentally, a nice bonus feature if interfaces could include statics would be a means of having them include extension methods for themselves. For example:
to allow an interface to expose to its users many overloaded versions of common functions without requiring all implementations to include the boilerplate code necessary to implement them.
我也多次问过自己这个问题,现在似乎想到了一个解释:
接口契约描述了对象的**做什么**,而不是**如何**做到这一点。构造函数可能与“如何”有更多的关系,所以这就是为什么我们不能将其作为契约的一部分。
接口的客户端期望接收一个已经构造的对象,因此他们不关心构造函数签名。至于将创建该对象的代码,它已经知道要创建什么具体对象,因此它知道构造函数签名。
I've also asked myself this question a few times, and one explanation seems to come to mind now:
The Interface contract describe **What** the object does, not **How** to do it. The constructor probably has more to do with the How, so that's why we can't make it part of the contract.
The clients of an interface expect to receive an already constructed object, so they don't care about the constructor signature. As for the code that will create that object, it already knows what concrete object to create, so it knows the constructor signature.
确实,Interface 没有构造函数,因为它们不知道什么类型的派生类将实现它。
但是我们可以有一个虚拟析构函数,以防我们不希望编译器隐式创建移动操作。
It's true that Interface doesn't have a constructor as they don't have any idea as to what type of derived class going to implement it.
But we can have a virtual destructor in case we don't want the compiler to implicitly create a move operation.
接口是契约,而不是实现,因此无需构造或销毁它们。您只需构造和销毁可以实现接口的具体类型。
Interfaces are contracts, not implementations, so no need to construct or destroy them. You only construct and destroy concrete types which could implement interfaces.
据我了解,你想知道为什么我们不能指定构造函数的签名以及其他对象的方法,就像
它不能这样做,因为首先,所有接口方法都应该实现为公共的,但构造函数可以设置为私有的,其次,方法 void App(..) 将仅是 App 类的构造函数,对于另一个类,它将是另一个方法。
因此,通常,如果您想指定具有已知参数的构造函数,请尝试使用抽象基类。
As I understand, you want to know why we can't specify constructor's signature as well as other object's methods, like
It can't be done because at first, all interface methods should be implemented as public but constructors can be set as private, and at second, method void App(..) will be constructor only for class App, for another class it will be another method.
So in common, if you want to specify constructor with known parameters, try to use abstract base classes.