如何覆盖从构造函数调用的基类方法

时间:2011-11-24 15:58:54

标签: c# class inheritance

我可能完全错了..

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类还会覆盖方法?

4 个答案:

答案 0 :(得分:2)

问题是你在构造函数中进行虚拟调用。此问题的机制和可能的解决方法详细here

简而言之,当您输入基类的构造函数时,尚未构造重写函数,因此调用基类中的虚函数。

答案 1 :(得分:2)

您无法从基类访问子类'实例成员。

它调用基类的doThing方法,因为就基类而言,这是唯一可用的doThing方法。如果你想让每个类的实例调用它自己的doThing方法,在你的子类中替换:

public DerivedClass(string x):base(x){}

使用:

public DerivedClass(string x)
{
    doThing(x);
}

答案 2 :(得分:0)

从设计角度来看,在构造函数调用期间,您应始终警惕“做事”。构造函数的目的仅仅是将类的实例转换为有效状态以供将来使用;它不应该试图“做”任何其他或有任何其他副作用。如果您的对象构造很复杂,您可能希望使用Builder或Factory模式来屏蔽调用代码的复杂性。

答案 3 :(得分:0)

这是因为您的DerivedClass使用了基本构造函数,并将result设置为base.doThing("test"),即“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类也重写方法?