为什么在构造函数之前调用类的成员方法
本文关键字:成员方法 调用 构造函数 为什么 | 更新日期: 2023-09-27 18:26:14
通常,构造函数是实例化时在类中执行的第一件事。
但在以下情况下,类的A成员方法首先执行&然后是构造函数。
为什么会这样?
代码场景:
namespace AbsPractice
{
class Program
{
static void Main(string[] args)
{
SavingsCustomer sc = new SavingsCustomer();
CorporateCustomer cc = new CorporateCustomer();
}
}
public abstract class Customer
{
protected Customer()
{
Console.WriteLine("Constructor of Abstract Customer");
Print();
}
protected abstract void Print();
}
public class SavingsCustomer : Customer
{
public SavingsCustomer()
{
Console.WriteLine("Constructor of SavingsCustomer");
}
protected override void Print()
{
Console.WriteLine("Print() Method of SavingsCustomer");
}
}
public class CorporateCustomer : Customer
{
public CorporateCustomer()
{
Console.WriteLine("Constructor of CorporateCustomer");
}
protected override void Print()
{
Console.WriteLine("Print() Method of CorporateCustomer");
}
}
}
这是因为当您调用SavingsCustomer
ctor时,首先调用它的基类ctor;在Customer
ctor中,您调用Print
,它是一个被重写的方法
因此,基本上在执行SavingsCustomer
ctor指令之前,必须完全调用Customer
ctor。请注意,当您从Customer
调用Print
时,会执行SavingsCustomer.Print()
。
这是预期的行为;如果您希望类的行为有所不同,则必须更改它们的逻辑。也许你不应该从基构造函数调用抽象方法,只是为了避免你现在看到的。。。
除非有充分的理由,否则永远不应该这样做。
从构造函数调用虚拟方法是一场等待发生的灾难。
在C#中,对象构造遵循类层次结构的顺序;也就是说,当调用构造函数时,首先调用最基本的类构造函数,然后调用立即派生的类构造函数、然后调用下一个,等等。
因此,当您从构造函数调用虚拟方法时,实际发生的情况是,如果虚拟方法被重写(在您的情况下,这是一种保证),将在调用实现类构造函数之前执行。这意味着该方法可以在对象的状态被正确初始化之前执行(通常通过构造函数;如果该方法不依赖于任何对象状态,那么这种模式就不是问题,尽管我仍然不建议这样做)。
如果绝对需要使用这种模式,那么良好的实践建议实现Initialize()
方法,并在那里执行任何虚拟调用。强制消费者在使用对象之前调用Initialize
是一项微不足道的任务,并且您可以保证在进行虚拟调用时对象的状态始终有效。
小问题。当你创建一个像这样的对象时
SavingsCustomer sc = new SavingsCustomer();
它调用Customer[类SavingsCustomer]的构造函数,意思是Customer()-从类SavingsCustomer调用Print(),因为它在Customerclass中是抽象的。尽管它是SavingsCustomer的成员函数,但在调用SavengsCustomerBecuasePrint()的构造函数之前,可以从Customer声明为抽象方法,因此它由这两个类共享
以下声明中也发生了同样的情况
CorporateCustomer cc = new CorporateCustomer();
CorporateCustomer类的Print()被调用,因为SavingsCustomer.Print()被覆盖