2011-04-04 59 views
20

我是在抽象類中尋找一些代碼:虛擬方法,而身體

public virtual void CountX(){} 

public virtual void DoCalculation() { ...code} 

我爲什麼要在一個抽象類中聲明一個空的虛方法,如果它不是強制性的覆蓋它派生類型?

+0

virutal。是的:) – Heliac 2013-08-20 19:06:05

回答

6

正如@Adam告訴你的,在很多情況下,它是有道理的。當你創建一個抽象類時,這是因爲你想爲所有派生的類創建一個通用接口;但是,在這種繼承級別下,您將沒有足夠的信息來爲該方法創建工作代碼。

例如,如果你創建類,與的getArea()方法,你將不能夠編寫是要正確計算該地區所有的數字代碼。您必須等待編寫代碼矩形(均源自),以便能夠爲其編寫工作代碼。

+5

以下代碼雖然在這種情況下,該方法應該是抽象的。由於您希望所有派生的形狀計算其面積,因此不要將其視爲「虛擬」。這種行爲不應該是可選的並且被排除在外。 – gretro 2014-09-08 02:24:07

+4

好的。如果你有20輛來自基類車輛的車輛,其中10輛沒有剎車裝置,但是你需要brake()方法,將它定義爲虛擬的(而不是抽象的) ,一個空的身體,而不是被迫覆蓋它在所有這些類別中什麼都不做。 – Baltasarq 2014-09-08 07:48:22

36

因爲如果默認行爲是什麼都不做,但派生類可能想做點什麼。這是一個非常有效的結構。

它允許您的基本代碼來調用它。當有「BeforeXXX」和「AfterXXX」代碼時,你傾向於看到類似的設計,在基類中這個代碼是空的,但該方法需要在那裏編譯。在派生類中,此代碼是可選的,但需要虛擬才能被覆蓋。

它在抽象類中的事實不應該混淆它的行爲。

一個例子:

abstract class Base 
    { 
     public void ProcessMessages(IMessage[] messages) 
     { 
      PreProcess(messages); 

      // Process. 

      PostProcess(messages); 
     } 

     public virtual void PreProcess(IMessage[] messages) 
     { 
      // Base class does nothing. 
     } 

     public virtual void PostProcess(IMessage[] messages) 
     { 
      // Base class does nothing. 
     } 
    } 

    class Derived : Base 
    { 
     public override void PostProcess(IMessage[] messages) 
     { 
      // Do something, log or whatever. 
     } 

     // Don't want to bother with pre-process. 
    } 

如果這些方法(前,後)是抽象的,那麼所有的派生類將需要實現它們(可能爲空的方法) - 可使用移除代碼垃圾在基地空的虛擬方法。

+0

+1 - 預處理和後處理是一個很好的例子。 – Town 2011-04-04 08:43:36

+0

+1:您將描述基本實現的位置作爲_default_行爲。這正是具有虛擬非抽象方法的目的。即使默認是「什麼都不做」,那仍然是默認設置;) – 2011-04-05 13:03:10

+0

嗯,所以如果我有一個「什麼都不做」的基本方法,*應該*我從這個調用base.DoNothingMethod(),DoNothingMethod,還是沒關係省略那段代碼? – Heliac 2013-08-20 19:17:54

3

當您將方法聲明爲抽象方法時,繼承的類具有以覆蓋該方法(提供實現)。這是強制性的。

當方法聲明爲虛擬時,繼承者可以用覆蓋該方法並提供一個不是默認的實現。

4

如果是強制重寫並且沒有默認邏輯可以寫入基類,那麼虛擬性是錯誤的,並且方法應該是抽象的。如果默認行動是什麼都不做,就像亞當所說的那樣,在基類中做空虛擬方法是完全有效的結構

0

從設計角度看,這味道不好,表明設計的實現處於不成熟的狀態。如果每個派生特定基類的類都不需要方法,那麼根據定義它不屬於基類。您通常會發現,此方法由基類的特定派生使用,並且在您的繼承層次結構中指示新的接口或抽象層。

+0

如果你打算投票。請至少提供一個理由。 – ComeIn 2014-10-27 03:09:06

+0

我同意Comeln。 DCastro的帖子在這裏(http://stackoverflow.com/questions/22256157/empty-virtual-method-on-base-class-vs-abstract-methods)揭示了這一點。 – Kwex 2015-08-06 12:24:19