Различие между абстрактным классом расширяется и расширяется нормальный класс


Есть ли какая-то четкая разница, почему использовать абстрактные для расширений, если мы можем сделать то же самое с обычными исключениями классов, для которых, например, не предусмотрен контракт.

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

Решение

То, что вы говорите, его правильное наследование работает в обоих случаях, но идея абстрактного класса заключается в том, что он является некоторой общей логикой, разделяемой классами x, которые расширяют эту функциональность, но сами по себе не могут быть созданы, поскольку это не имеет смысла (возможно, вы хотите, чтобы в вашей системе были только типы автомобилей, а не универсальный автомобиль без марки)

2

Другие решения

Также, если вы будете использовать обычный класс и интерфейс, вы будете вынуждены создать заглушку в классе, чтобы следовать контракту. Таким образом, вы сможете создать экземпляр класса. И только представьте, что вы будете использовать эту общую функцию в вашем высшем классе.

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.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector