【发布时间】:2011-04-08 18:11:53
【问题描述】:
类可以有虚拟构造函数吗?
如果是,为什么需要它?
【问题讨论】:
类可以有虚拟构造函数吗?
如果是,为什么需要它?
【问题讨论】:
仅供参考,当人们要求虚拟构造函数时,一个非常好的模式是InversionOfControl
在 .NET 中,我们有几个 IoC 容器,例如 ObjectBuilder、Unity、MEF、Spring.NET。在 Java 中(有炫耀我的 Java 无能的风险)有 Spring、Tapestry 和许多其他。
恕我直言,IoC 是 OO 兑现承诺的原因。
【讨论】:
根据定义,虚拟方法是根据接收方的运行时类型分析而不是接收方的编译时静态类型分析来调度的方法。
构造函数是在创建特定类型的新实例时调用的方法。
由于新创建对象的运行时类型与其编译时类型总是相同 (*),因此不需要虚拟构造函数:运行时调度总是选择相同的方法作为静态调度,何必费心去改变呢?
(*) 这并不完全正确;在某些涉及 COM 互操作的场景中,构造的运行时类型不是编译时类型。在遗留互操作代码的世界中,很多事情都很奇怪。
【讨论】:
不,类不能有虚拟构造函数。
拥有一个虚拟构造函数是没有意义的。在 C# 中构造对象的顺序是先构造派生类,因此始终调用派生构造函数,因为在构造时要调用的类是众所周知的。
另一件事是,如果你真的把这段代码输入出来,你很快就会发现它毫无意义
如果你有:
public class BaseClass
{
public virtual BaseClass()
{
}
}
然后
public class InheritedClass : BaseClass
{
//overrides baseclass constructor but why would you do this given that the
//constructor is always going to be called anyway??
public override InheritedClass()
{
}
}
【讨论】:
如果我们查看构造函数和虚拟这个词的定义,我们会得出一个合乎逻辑的结论,即构造函数不能是虚拟的。
【讨论】:
不,它是如何工作的?当您从基类派生子类时,必须调用层次结构中的所有构造函数。将构造函数设为虚拟则意味着其他情况。
当您使用工厂模式时,可能会被描述为具有类似虚拟构造函数的行为。想象一下这种情况:
class AnimalFactory
{
virtual Animal CreateAnimal( return new Animal("Cow"); );
}
这个工厂的默认行为是创建奶牛。但是如果我们创建一个派生类:
class DogFactory : AnimnalFactory
{
override Animal CreateAnimal( return new Animal("Dog"); );
}
我们现在正在创造狗。当然这不是真正的虚构造函数(这是不可能的),这是虚构造函数。
【讨论】:
不是直接的,但是经典的四人帮模式工厂方法通过将实例化推迟到子类来实现相当于某种虚拟构造函数。
【讨论】:
声明一些虚拟的东西意味着它可以被当前类的子类覆盖。但是,在实例化类时会调用构造函数。那时您不能创建相关类的子类,因此永远不需要声明构造函数 virtual。
【讨论】: