Классы разрабатываются с целью расширения или без намерения расширения. Если ваш класс не намерен быть родителем, его следует указать как окончательный. Класс, предназначенный для расширения, обязан заложить основу, из которой ребенок будет работать. Любые методы, определяющие правила фреймворка, должны быть указаны как final.
Это описание столь же расплывчато, как и вопрос.
Мне нравится пример учета от Anurag и я хочу показать, как правильно использовать.
abstract class Account {
// obtained by some magical source
private $balance = 100.00;
final public function getBalance() {
return $this->balance;
}
final private function setBalance($new_balance) {
$this->balance = $new_balance;
}
final public function debit(Amount $amount) {
if ($this->canDebit($amount)) {
$amount = $amount + $this->getDebitTransactionFee();
$this->setBalance($this->getBalance() - $amount);
}
}
abstract protected function canDebit();
abstract protected function getDebitTransactionFee();
}
final class CheckingAccount extends Account {
final protected function canDebit() {
return true;
}
final protected function getDebitTransactionFee() {
// obtained by some magical source
return 1.50;
}
}
Ответственность Аккаунта состоит в том, чтобы следить за балансом, разрешать общественности дебетовать и разрешать общественности проверять текущий баланс. Ответственность CheckingAccount состоит в том, чтобы ответить, если он может быть списан, и сообщить о соответствующей комиссии за транзакцию. Очевидно, что учет здесь чрезвычайно упрощен. Этот пример - одна из наиболее вероятных бесконечных ситуаций.
Абстрактные классы довольно распространены для классов, предназначенных для расширения. Иногда, однако, класс может определять свои собственные неконечные методы с функцией по умолчанию и иметь рабочий экземпляр. Конечно, будучи не финальными, эти методы по умолчанию могут быть переопределены дочерним классом.