2010-04-23 2 views
4

Что может быть примером сценариев для объявления любого класса или любого метода как «окончательного»? Когда нам это нужно?Что может быть примером сценариев для объявления любого класса или любого метода как «окончательного»?

Пожалуйста, дайте мне пример, чтобы понять практическое применение «окончательный» ...

просьба уточнить ваш ответ ....

, пожалуйста, руководство меня, как я новичок в ООП

+1

, чтобы избежать расширения и модификации класса/метода. вы можете найти это обсуждение интересным, почему строки являются окончательными в Java - http: // stackoverflow.com/questions/2068804/why-is-string-final-in-java – Anurag

+0

@ Анураг точки в отношении «неизменности» и других таких сложных терминов выходят за рамки моего ума :) может у вас, может быть, все это выдумаете? –

+0

отправил ответ на основной пример. – Anurag

ответ

5

Это просто пример того, почему методы/классы необходимо блокировать иногда из любых дальнейших расширений, чтобы избежать неожиданностей.

class Account { 
    public function debit(Amount $amount) { 
     if(($this->canDebit($amount)) { 
      $this->balance -= $amount; 
     } 
    } 

    final public function credit(Amount $amount) { 
     ... 
    } 
} 

class CheckingAccount extends Account { 
    public function debit(Amount $amount) { 
     // we forgot to check if user canDebit() 
     $this->balance -= $amount; 
    } 
} 

Это просто пример, иллюстрирующий, почему необходимо сделать методы и классы окончательными. На самом деле, очень хорошая практика сделать все ваши методы и классы окончательными , если вы знаете, что собираетесь расширять их, а подклассы могут (и будут разрешены) расширять/переопределять базовый класс.

+0

«Это очень хорошая практика, чтобы сделать все ваши методы и классы окончательными, если вы не знаете, что собираетесь расширять их, и подклассы могут захотеть (и будет разрешено) расширять/переопределять базовые классы. " Я последую за этим ... Я понял пример, но я сомневаюсь, что это тоже сделано для целей безопасности? Если да, то Y, зачем нужно его защищать? –

+0

по тем же причинам .. этот пример выше, возможно, был невинной ошибкой, но могут быть и вредоносные классы .. прочитайте этот раздел 1.2 для получения дополнительной информации - http://java.sun.com/security/seccodeguide. html # 1-2 – Anurag

+0

Спасибо Это помогло мне .... :) –

0

только для статического класса, вы могли бы сделать

final private function __construct() 
{ 
// This is a static class 
} 

нравится, как Kohana does it.

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

Поэтому, если они попытаются его расширить, они получат сообщение об ошибке и знают , почему они не могли.

+1

пожалуйста, уточните ... –

2

В принципе, вы объявляете какой-либо выпуск класса, если считаете, что его больше не следует расширять, или вам не нужно ни вы, ни кто-либо другой расширять этот класс.

+1

Но почему? Должна быть какая-то конкретная причина, например, мудрость, которую мы имеем для спецификаторов доступа ... –

1

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

Это описание является таким же неопределенным, как и вопрос.

Мне нравится пример учета от 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 заключается в том, чтобы ответить, если он может быть дебетован и сообщить о соответствующей комиссии за транзакцию. Очевидно, что учет здесь чрезвычайно упрощен. Этот пример - одна из вероятных бесконечных ситуаций.

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