我知道这个接口正在工作。当我开始在我的项目中编码时,我心中产生了疑问。有人能够澄清一下吗?
我知道这个接口正在工作。当我开始在我的项目中编码时,我心中产生了疑问。有人能够澄清一下吗?
接口是合同,而不是实现,因此无需构建或销毁它们。您只需构建和销毁可能实现接口的具体类型即可。
据我了解,您想知道为什么我们不能像其他对象的方法一样指定构造函数的签名,例如
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){ }
}
接口只是对象之间的契约,它们本身没有任何代码。如果你给它们构造函数和析构函数,那就相当于给它们添加需要执行的代码。如果你需要在契约中进行初始化或清理操作,可以添加Initialize() 和 Uninitialize() 方法。
因为接口本身无法构建或销毁,它只是一个概念,一份契约。
声明和定义接口的过程就是构建接口,它们不是可以实例化的对象。
我认同接口是一种"契约"。就我的个人看法而言,我希望能够将构造函数签名作为这个契约的一部分进行指定。
但是,我喜欢像 Pascal 和 Ada 这样的语言,它们都非常努力地规定了一个正式的 "接口",与 "实现" 分开并且相互独立。
不管怎样,从实践和理论上讲,有很多原因可以排除构造函数(甚至构造函数定义)出接口。在 C# 和 Java 中,这些论点基本上是相同的。以下链接非常有启发性:
我基本上同意这些观点:
可以定义一个静态类,名称与接口相似,其中包括工厂方法或属性来生成实现接口的类实例。例如,Enumerable<T>.Empty和Comparer<T>.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); } static void SetSize(int width, int height) { It.SetBounds(0, 0, width, height, BoundsSpecified.Size); }
为了让接口向其用户公开许多常见函数的重载版本,而不需要所有实现都包含必要的样板代码来实现它们。
我也曾经问过自己这个问题,现在似乎有一个解释:
接口合同描述对象做什么,而不是如何做。构造函数可能与如何做更相关,因此我们不能将其作为合同的一部分。
接口的客户端希望收到一个已经构建好的对象,因此他们不关心构造函数的签名。至于将创建该对象的代码,它已经知道要创建什么具体对象,因此它知道构造函数的签名。
确实,接口没有构造函数,因为它们不知道哪种派生类将要实现它。
但是,我们可以有一个虚析构函数,以防止编译器隐式创建移动操作。