2016-01-24 86 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合同。