2015-11-08 42 views
3

這是一個關於繼承應該如何使用的簡單問題。繼承:使用基類或派生類來做東西

考慮到我必須提供業務邏輯來打印'foo'和'bar',並且我有兩個類的層次結構:一個只有'foo'打印方法,另一個先打印'並且有方法打印'酒吧'。 在這兩個類中,我都有一個名爲necessaryMethod()的方法,它負責調用打印'foo'和'bar'的方法。

的方式我實現它在兩種方法:

第一種方法是讓基類做一些東西和派生類利用它的優勢。第二種方法是讓基類不做任何事情(只提供實現)並將所有責任都放在派生類上。

考慮下面的代碼:

方法1:

public class A{ 

    protected void necessaryMethod(){ 
     callFoo(); 
    } 

    protected void callFoo(){ 
     System.out.pritln("foo"); 
    }  
} 

public class B extends A{ 

    @Override 
    protected void necessaryMethod(){ 
     super.necessaryMethod(); 
     callBar(); 
    } 

    protected void callBar(){ 
     System.out.println("bar"); 
    } 
} 

public class FooBarClass{ 
    public static void main(String args[]){ 
     B b = new B(); 
     b.necessaryMethod(); 
    } 
} 

方法2:

public abstract class A{ 

    protected abstract void necessaryMethod(); 

    protected void callFoo(){ 
     System.out.pritln("foo"); 
    }  
} 

public class B extends A{ 

    @Override 
    protected void necessaryMethod(){ 
     calFoo(); 
     callBar(); 
    } 

    protected void callBar(){ 
     System.out.println("bar"); 
    } 
} 

public class FooBarClass{ 
    public static void main(String args[]){ 
     B b = new B(); 
     b.necessaryMethod(); 
    } 
} 

哪種方法將是可維護性和代碼的可讀性(不錯在大型軟件產品/大類層次結構的背景下;這一點只是一個例子)?

(這是一個通用的編程問題,我並沒有要求的意見。)

+1

這個問題在http://codereview.stackexchange.com/上更合適。 – jaco0646

+0

@ jaco0646如何遷移問題? –

回答

1

如果要使用派生類,但掩蓋他們作爲基類,基類應該有派生類中的每一個功能(因爲你告訴物體「認爲」它是A而忘記它是B)。所以,在我看來,最好的辦法是:

public abstract class A{ 
    protected abstract void callBar(); 
    protected abstract void callFooBar(); 
    protected void callFoo() { 
     System.out.pritln("foo"); 
    } 
} 

public class B extends A { 
@Override 
    protected void callBar(){ 
    System.out.println("bar") 
    } 
@Override 
    protected void callFooBar(){ 
    callFoo(); 
    callBar(); 
    } 
} 

然後調用B,爲這樣的:

A b = new B(); 
b.callFooBar(); 

我認爲這是相當維護,因爲一旦你創建的基類,你是非常靈活用派生類可以做什麼,並且與基類相比,你總是比派生類提前一步。除非你嘗試過度休息,這總是不好的。總是嘗試只有一級繼承,偶爾兩個。其他任何事情都會很快失去控制,如果你需要這麼多繼承,那麼評估接口是不是更好的選擇可能是個好主意。

2

遠離編程的技術方面,某種行爲(它的方法)有助於定義它。即狗吠()。

一般的問題是:

  1. 是否行爲callFoo()讓你覺得一個 'A'(A類),或 'B' 的?

1.1。在他們將屬於編程之外的類中組織方法(行爲) - 定義類。

大型代碼庫

即使B的可能屬於在現實世界中的集合A的,有時太多的繼承可以對着幹導航和維護代碼。繼承的目的更重要,實現繼承本身並且不要使用繼承可能會更好。

我在一年前實現了一個龐大的代碼庫,對它背後的複雜UML感到非常自豪,但最近重新訪問它是一場噩夢。在某些地方,我可以選擇使用繼承或不使用更多的自由裁量權。

在這種情況下的問題是:這種繼承有助於組織代碼嗎?它會幫助另一位程序員嗎?

抽象類

是否有意義在你的程序中的任何一點來實例化超類的實例,代替它的子類之一?如果不是,那麼抽象超類獲得投票。

+0

+1是關於實施的責任而不是技術約束。對GRASP的引用可能有用:https://en.wikipedia.org/wiki/GRASP_(objectject-oriented_design) – Guillaume

相關問題