2012-11-23 248 views
11

OOP的新手,我很遺憾繼承自C#中的基類時,派生類構造函數是如何工作的。構造函數參數和繼承

首先是基類:

class BaseClass 
{ 
    private string BaseOutput = null; 

    public BaseClass(string BaseString) 
    { 
     BaseOutput = BaseString; 
    } 

    public virtual void PrintLine() 
    { 
     Console.WriteLine(BaseOutput); 
    } 
} 

這裏是派生類:

class SubClass : BaseClass 
{ 
    private string SubOutput = null; 

    public SubClass(string BaseString, string SubString) : base(BaseString) 
    { 
     SubOutput = SubString; 
    } 

    public override void PrintLine() 
    { 
     Console.WriteLine(SubOutput); 
    } 
} 

最後,該方案的主要組成部分:

class Program 
{ 
    static void Main(string[] args) 
    { 
     BaseClass theBase = new BaseClass("Text for BaseClass"); 
     SubClass theSub = new SubClass("2nd param", "Text for SubClass"); 

     theBase.PrintLine(); 
     theSub.PrintLine(); 

     Console.ReadKey(); 
    } 
} 

我也不是什麼get是爲什麼,當調用派生類的構造函數時,我還必須傳遞基類所需的參數。如果沒有賦值,派生類中的BaseOutput字段不應該保持爲空嗎?爲什麼不能像這樣工作:

public SubClass(string SubString) : base(BaseString) 

此外,在這個派生類中調用構造函數的時候,第一個參數必須命名一樣的一個基類,否則它拋出一個錯誤。如果我是在派生類中定義名爲AnotherString新的字符串變量,爲什麼不這項工作:

public SubClass(string AnotherString, string SubString) : base(BaseString) 

最後,當你這樣做的正確方法,並輸入了這...

public SubClass(string BaseString, string SubString) : base(BaseString) 

... SubClass構造函數中用到的第一個參數是什麼?它沒有被派生或用於我的派生類的任何方法。爲什麼我甚至不得不把它放在那裏呢?

+0

直到您調用子類構造函數爲止,它的存儲時間爲秒。然後用你的「2nd param」參數字符串覆蓋它。 –

回答

14

至於爲什麼你不能這樣做:

public SubClass(string SubString) : base(BaseString) 

BaseString會是什麼?

你可以這樣做:

public SubClass(string SubString) : base("SomeFixedString") 

public SubClass(string SubString) : base(SubString) 

但是,如果你想要一個字符串傳遞給基類構造函數的參數,並有額外的一個,你需要接受兩個參數。

至於保持相同的名稱,你不要。你可以這樣做:

public SubClass(string AnotherString, string SubString) : base(AnotherString) 

至於最後一個問題,第一個參數沒有做任何事,它被傳遞給基類的構造函數。如果你願意,你可以用它來做其他事情。

+0

這對我來說更有意義了,謝謝。 'BaseClass'需要將信息傳遞給它的構造函數,並將其從您放入派生構造函數中的內容中抽取出來。 – Frank

1

如果你想用默認值初始化BaseString,然後傳遞價值的基類構造函數(因此你不必給該參數傳遞給派生類的構造函數)

public SubClass(string SubString) : base(null) 

或者在定義參數的構造函數基類。

另外關於參數命名 - 哪個名稱有參數,哪個名稱傳遞給派生構造函數並不重要。唯一重要的是你傳遞給基礎構造函數的值。

public SubClass(string AnotherString, string SubString) : base(AnotherString) 
1
public SubClass(string BaseString, string SubString) : base(BaseString) 

此構造函數在派生類中說,當你收到兩個參數BaseStringSubString,調用基類的構造函數與BaseString

因此,做

public SubClass(string a, string b) : base(BaseString) 

不起作用,因爲你告訴它要調用基類的構造函數與BaseString但目前還沒有說法叫BaseString

如果你想實例化派生類沒有通過字符串基類的構造函數,基類需要一個默認的構造函數:

public BaseClass() { } 
1

如果要提供機會派生類沒有設置即basestring,那麼你就需要提供這樣的基類的默認構造函數:在派生類中

public BaseClass() 
{ 

} 

現在,你可以調用不帶參數的構造函數在基類中是這樣的:

public SubClass(string AnotherString) 
    : base() 
{ 
    // base() => explicit call to default construct in the base class. 
    // Do something else 
} 

這提供了良好的軟件工程實踐:如果要提供機會不要設置基類的字符串,然後在基類中這樣做。其他的'黑客'就像將null作爲參數傳遞給基類構造函數一樣,只能用於不應該從子類中完成的基類內部修補。

+0

閱讀了其他一些回覆之後,我可以肯定地看到有一個默認構造函數的價值。我會從現在開始,而不是傳遞虛擬值,謝謝! – Frank