如何覆盖从构造函数调用的基类方法
Posted
技术标签:
【中文标题】如何覆盖从构造函数调用的基类方法【英文标题】:how to override a base class method called from a constructor 【发布时间】:2011-11-24 15:58:53 【问题描述】:我可能完全错了..
public class BaseClass
public string result get; set;
public BaseClass()
public BaseClass(string x)
result = doThing(x);
public virtual string doThing(string x)
return x;
public class DerivedClass : BaseClass
public DerivedClass()
public DerivedClass(string x):base(x)
public override string doThing(string x)
return "override" + x;
我希望新的 DerivedClass("test") 具有“overridetest”的结果,但它没有:它调用 doThing 的基本方法。我错过了什么吗?我是否需要创建一个 AbstractClass 并让 BaseClass 和 DerivedClass 都继承自它,Derived 类也覆盖方法?
【问题讨论】:
Calling virtual method in base class constructor的可能重复 它并不完全是重复的——这与 ste 的有效性有关,在我的情况下,派生的 doThing 永远不会被调用。 【参考方案1】:问题是您在构造函数中进行了虚拟调用。此问题的机制和可能的解决方法在here 中有详细说明。
总之,当你进入基类的构造函数时,被覆盖的函数还没有被构造出来,所以调用了基类中的虚函数。
【讨论】:
在发布的代码中,由于静态编译器绑定,当控件位于基类的构造函数中时,重写的函数是可用。派生类的方法不会被调用,因为您无法从基类访问任何派生类的非静态成员。【参考方案2】:您不能从基类访问子类的实例成员。
它调用基类的doThing
方法,因为就基类而言,这是唯一可用的doThing
方法。如果您想要每个类的实例调用它自己的 doThing
方法,请在您的子类中替换:
public DerivedClass(string x):base(x)
与:
public DerivedClass(string x)
doThing(x);
【讨论】:
【参考方案3】:从设计的角度来看,在构造函数调用期间,您应该始终警惕“做事”。构造函数的目的仅仅是使类的实例进入有效状态以供将来使用;它不应该尝试“做”任何其他事情或产生任何其他副作用。如果您的对象构造是一件复杂的事情,您可能希望使用 Builder 或 Factory 模式来屏蔽调用代码的复杂性。
【讨论】:
【参考方案4】:这是因为您的DerivedClass
使用基本构造函数并将result
设置为base.doThing("test")
,即“测试”。
所以您可以将您的 DerivedClass
更改为:
public class DerivedClass : BaseClass
public DerivedClass()
public DerivedClass(string x):base(x)
result="override"+x;
//or as result already be set as x, you can use: result="override" + result;
或者如你所说,
需要创建一个 AbstractClass 并同时具有 BaseClass 和 DerivedClass 继承自那个,Derived 类也重写方法?
【讨论】:
以上是关于如何覆盖从构造函数调用的基类方法的主要内容,如果未能解决你的问题,请参考以下文章