簡體   English   中英

如何覆蓋從構造函數調用的基類方法

[英]how to override a base class method called from a constructor

我可能這樣做完全錯了..

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類還會覆蓋方法?

問題是你在構造函數中進行虛擬調用。 這里詳細介紹了此問題的機制和可能的解決方法。

簡而言之,當您輸入基類的構造函數時,尚未構造重寫函數,因此調用基類中的虛函數。

您無法從基類訪問子類的實例成員。

它調用基類的doThing方法,因為就基類doThing ,這是唯一可用的doThing方法。 如果你想要每個類的一個實例調用它自己的doThing方法,在你的子類中替換:

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

有:

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

從設計角度來看,在構造函數調用期間,您應始終警惕“做事”。 構造函數的目的僅僅是將類的實例轉換為有效狀態以供將來使用; 它不應該試圖“做”任何其他或有任何其他副作用。 如果您的對象構造是一個復雜的事情,您可能希望使用Builder或Factory模式來屏蔽調用代碼的復雜性。

這是因為你的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類還會覆蓋方法嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM