2015-12-17 5 views
1

Есть ли причина использовать ключевое слово private вместо protected? Я могу понять цель этого, когда есть какое-то свойство кэширования или вспомогательный метод, который не имеет смысла в дочернем классе. Я вижу private во многих важных классах, хотя, где я не вижу цели. Вот пример Symfony: Symfony's HttpException class:В объектно-ориентированном мире используется личное ключевое слово overused?

namespace Symfony\Component\HttpKernel\Exception; 

class HttpException extends \RuntimeException implements HttpExceptionInterface 
{ 
    private $statusCode; 
    private $headers; 

    public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = array(), $code = 0) 
    { 
     $this->statusCode = $statusCode; 
     $this->headers = $headers; 

     parent::__construct($message, $code, $previous); 
    } 

    public function getStatusCode() 
    { 
     return $this->statusCode; 
    } 

    public function getHeaders() 
    { 
     return $this->headers; 
    } 
} 

Есть ли какая-либо причина, почему те не protected? Единственное, о чем я могу думать, это заставить программистов объявить их самостоятельно для чтения кода, но я не настолько уверен в этом. Пожалуйста, дайте мне знать, что вы думаете об использовании ключевого слова private.

+0

«Многие хорошие вопросы порождают определенное мнение, основанное на опыте экспертов, но ответы на этот вопрос будут иметь тенденцию почти полностью основываться на мнениях, а не на фактах, ссылках или конкретном опыте». –

+0

В большом количестве кода, который я видел, 'private' был недостаточно использован, и объекты обрабатывались как записи с помощью методов. – reaanb

+0

@reaanb Возможно, вы говорите о злоупотреблении 'public', но это обсуждение о' private' против 'protected', а не' private' vs. 'public'. –

ответ

0

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

+0

Разве это не то, что для ключевого слова 'final', а не' private'? –

+0

final на классе или методе означает, что он не может быть расширен или переопределен. Добавление дополнительного защищенного классификатора делает вызываемым из подкласса; частные методы не видны за пределами класса –

+0

, последнее поле означает, что он не может быть изменен после его назначения –

1

Да, есть абсолютно причина, и эта причина - принцип замещения Лискова или «L» в «SOLID», если вы предпочитаете.

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

protected Члены являются распространенным методом создания нарушений подстановки Liskov, поскольку они позволяют вам перезаписывать поведение, обнаруженное в супертипе.

Это здорово в теории, но что это на самом деле означает?

is взаимосвязь, созданная наследованием, является чрезвычайно прочной связью между типами, гораздо более сильной, чем общий интерфейс или композиция, поскольку она подразумевает совместное использование. Классическим примером нарушения замещения Лискова является проблема Circle-Ellipse, см.: https://en.wikipedia.org/wiki/Circle-ellipse_problem

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

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

Важно знать, что вы не пропустите детали реализации своего класса за пределами своих границ через членов protected, как и через public, потому что подводные камни могут быть немного неприятными.

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


Давайте посмотрим на вашем примере, имеет код в private статус, например. На данный момент этот код состояния является фактически неизменным, он устанавливается один раз в конструкторе и не может быть изменен каким-либо открытым способом в классе. Это хорошо, потому что это исключение, мы не хотим, чтобы он менялся, мы хотим знать о том, что изначально вызвало его.

Если бы вы были, чтобы сделать этих членов protected, у вас нет никакой гарантии на это. Подтип HttpException, который представляет собой одну ошибку за один момент, теоретически может представлять совершенно другую ошибку на следующем. В этой ситуации класс больше не имеет смысла, он не служит своей цели.

 Смежные вопросы

  • Нет связанных вопросов^_^