如果我们可以在普通类中做同样的事情,为什么使用抽象扩展是否有任何明显的区别,除非它不提供例如的合同。
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
}
现在,除了合同方法之外,普通类可以通过扩展来授予相同的功能,对于合同我们也可以使用接口。
答案 0 :(得分:2)
你所说的正确的继承在两种情况下都有效,但是抽象类的想法是它的一些共同逻辑由x类共享,这些逻辑扩展了这个功能但是它不能自我实例化,因为它没有意义(也许你只想在你的系统中使用各种类型的汽车,而不是没有品牌的通用汽车)
答案 1 :(得分: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
答案 2 :(得分:1)
只要您需要合同,就应该使用界面。你应该使用抽象类,以防某些simmilar类有一个共同的功能,你不想重复代码(DRY :)。当然,使用合成总是更好,但现在不是讨论的时候:)
您的代码(使用Survivalneeds类)的问题在于,一方的类负责合同(呼吸和吃方法),另一方负责提供通用功能。您可以通过以下方式更改代码:
interface Survivor {
public function eat();
public function breathe();
}
abstract class Survivalneeds implements Survivor {
public function breathe() {
// method's body
}
}
通过这样的实施,责任被分割。同样很明显,所有延长生存期的课程都需要完成幸存者合同。