2016-01-24 129 views
0

是否有任何明顯的區別爲什麼使用抽象擴展如果我們可以在普通類中做同樣的事情,除非它沒有提供例如。抽象類擴展和普通類之間的區別延伸

abstract class Survivalneeds { 

abstract public function eat(); // everyone eats but different foods which would probably work as contract 

public function breathe() { 

// everyone inhale o2 exhale co2 only for animals 

} 

} 

現在

class human extends Survivalneeds { 

    protected function eat() { 
//sometimes eat goat 
// contract    
} 

breathe()// already extending having same functionality inhale o2 and exhale co2 



} 

class goat extends Survivalneeds{ 

protected function eat() { 
//wee eat greens 
// contract    
} 

breathe()// already extending having same functionality inhale o2 and exhale co2 

} 

現在相同的功能,可以通過正常類由除合同法延長理所當然的合同,我們可以使用的界面也。

回答

2

你在說什麼它的正確繼承在兩種情況下都有效,但是抽象類的思想是它由x類共享的一些通用邏輯擴展了這個功能,但它不能由它自己實例化,因爲它沒有(也許你只想在你的系統中有類型的汽車,但不是沒有品牌的通用汽車)

+0

所以我們創造的抽象只是因爲它在這裏不可實例化? –

+0

抽象方法也非常有用,檢查模板方法模式[link](https://sourcemaking.com/design_patterns/template_method) – Nautilus

1

此外,如果你將使用常規的類和接口,你將被迫在類中創建存根以遵守合同。所以你將能夠創建這個類的實例。想象一下你會在你的上流社會中使用這個共同的功能。

interface Crashable{ 

    function crash(); 
} 
class Car implements Crashable{ 
    function crash(){} 
    function getCrashParams(){ 
     return $this->crash(); 
    } 
} 
class Volvo extends Car{ 
    function crash(){ 
     parent::crash(); // will be OK that it's not right 
     //.. specific params 
     return $params; 
    } 
} 
class Saab{ 
    function crash(){ 
     //.. specific params 
     return $params; 
    } 
} 

$car = new Car(); // will be ok, that it's not right 

//getCrashParams() function in a Car will use the local version of the crash() and not the function of it's child that will kill the data flow 
1

您應該在需要合同時使用接口。您應該使用抽象類來防止某些類似類的通用功能,並且您不想重複該代碼(DRY :)。當然,使用合成總是比較好,但這不是討論時間:)

您的代碼(帶有Survivalneeds類)的問題是事實上,來自一方的類負責合同(呼吸和吃方法),並從另一個負責提供共同的功能。您可以通過以下方式更改代碼:

interface Survivor { 
    public function eat(); 
    public function breathe(); 
} 

abstract class Survivalneeds implements Survivor { 
    public function breathe() { 
     // method's body 
    } 
} 

將此類實施責任分開。另外很明顯,所有將延續Survivalneeds的類別都需要履行Survivor合同。