2014-07-16 87 views
11

我有一個抽象基類:爲什麼我可以抽象重寫一個抽象方法?

abstract class Foo 
{ 
    virtual void DoSomeStuff() 
    { 
     //Do Some Stuff 
    } 

    abstract void DoSomeCrazyStuff(); 
} 

,並從該派生出的另一抽象類:

abstract class Bar : Foo 
{ 
    abstract override void DoSomeStuff(); 

    abstract override void DoSomeCrazyStuff(); 
} 

我明白你爲什麼會想抽象覆蓋DoSomeStuff() - 這將需要一個新的實現進一步派生類。但我無法弄清楚爲什麼你想抽象覆蓋DoSomeCrazyStuff()。據我所知,這是多餘的 - 我很確定刪除它將不會產生負面影響。

是否存在一些抽象重寫對抽象操作有用的用例?如果沒有,爲什麼沒有編譯器警告,告訴我我寫的內容什麼都不做?

+1

這個鏈接可以幫助 - 「因爲規範是這麼說的」 http://msdn.microsoft.com/en-us/library/ms173150%28VS.80%29.aspx – terrybozzio

+3

此落在範疇 –

+0

看起來像是Roslyn的一個很好的功能請求。 –

回答

3

爲什麼我可以抽象重寫一個抽象方法?

對於初學者來說,沒有防止它的實際原因。如果它產生了一個編譯器錯誤,那麼所做的只是讓類變得更脆弱。例如:

abstract class Foo 
{ 
    virtual void DoSomeStuff() 
    { 
     //Do Some Stuff 
    } 
} 

abstract class Bar : Foo 
{ 
    abstract override void DoSomeStuff(); 
} 

如果抽象抽象的覆蓋是非法的,在Foo上改變DoSomeStuff抽象現在會阻止從酒吧編譯。抽象覆蓋是多餘的,但沒有潛在的負面影響,所以編譯器可以做到這一點。


爲什麼沒有一個編譯器警告,通知我說什麼,我已經寫了什麼也不做?

編譯器生成的警告對於表示風險某些事情:非顯式方法隱藏,無法訪問的代碼,使用過時的方法等的唯一的「問題」的不必要的抽象倍率可指示的是,代碼是不能有效地書面。這不是編譯器關心的問題。


是否存在這樣一種抽象的抽象的覆蓋做一些有用的一些使用情況?

沒有功能。但是,有幾種用例可能會故意這樣做:

  • 提高代碼的「可讀性」。具有冗餘抽象覆蓋將提醒該方法是抽象的。
  • 如果未來對基類的更改包括提供虛擬實現,則可以預先阻止某些類訪問該基類。
  • 如果抽象重寫是多餘的,因爲基類已從虛擬實現更改爲抽象,它可以安全地放置。
2

通過明確abstract overrideBar荷蘭國際集團它,你要確保它會通過Bar的後裔們被看作是抽象的,即使在Foo將來可能會變成一個非抽象之一。儘管有這樣的變化,Bar的後代將與同樣的合同工作。

+0

我看到了這方面的實用價值,但這不是對Liskov Substitution的違反嗎?任何對'Foo'進行操作並期待具體的'DoSomeCrazyStuff'的方法在傳遞一個'Bar'時會中斷。 –

+2

@AustinMullins Bar和DoSomeCrazyStuff仍然是抽象的,所以沒有什麼會在Bar上運行,而是一個具體的類,如果沒有實現所有的抽象方法就不能編譯。 – User

+0

@OndrejTucny您不需要額外的抽象覆蓋來防止合同更改,現有的'Bar'覆蓋仍然會覆蓋虛擬實現。它是先發制人地阻止'Bar'的後代被寫入''Foo's被更改爲虛擬的訪問基礎實現。爲什麼要阻止訪問尚未寫入的方法?爲什麼不保存該決定,直到方法實際寫入? – User

相關問題