Когда я должен использовать «финал»? - PullRequest
12 голосов
/ 08 февраля 2009

Есть ли какая-то особая причина, по которой я должен объявить класс или метод final в повседневном программировании (веб или иным образом)? Пожалуйста, приведите пример из реальной жизни, где его следует использовать.

Кстати, я спрашиваю, потому что я пытаюсь выбрать "неясное" ключевое слово и освоить его .

Ответы [ 6 ]

12 голосов
/ 08 февраля 2009

Это мешает другим программистам делать вещи с вашими классами, которые вы не собираетесь делать для них. Поэтому вместо того, чтобы комментировать слова «не используйте этот класс для выполнения XXX», вы можете создать его таким образом, чтобы у них не было соблазна переопределить его и злоупотребить таким образом.

Редактировать : Поскольку требуется пример, я опишу случай, когда вам может пригодиться это ключевое слово ... скажем, у вас есть класс, который определяет, как два объекта могут взаимодействовать друг с другом, скажем, слушатель и уведомитель. Класс слушателя, очевидно, должен разрешать наследование, но вы можете захотеть сделать класс уведомителя окончательным, чтобы его можно было использовать в отношениях «есть». Таким образом, вы можете сделать некоторые предположения от ваших объектов-слушателей о природе сообщений, которые они получают.

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

Другой пример - скажем, у вас есть потоковый процессор на основе буфера, и внутри вашего метода read () / write () вы храните некоторые данные о текущем состоянии вашего объекта (т. Е. Текущий байт или что-то еще) , Невозможно гарантировать, что кто-либо из подклассов этого класса будет вызывать методы супер во время обработки - и поскольку такой класс, скорее всего, содержит всего несколько методов, лучше просто сделать все окончательным, а не каждый метод. Это снова вынуждает людей, использующих класс, иметь «имеет-а», а не «есть-а», и, таким образом, может контролировать, как вы ожидаете, код будет выполняться.

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

6 голосов
/ 08 февраля 2009

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

3 голосов
/ 08 февраля 2009

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

2 голосов
/ 09 февраля 2009

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

Если вы хотите реализовать намерение класса, и намерение таково, что не имеет смысла создавать подклассы, тогда используйте final; в противном случае нет существенного преимущества.

В общем, это всего лишь механизм реализации намерения.

0 голосов
/ 08 февраля 2009

final (и запечатанный в c #) может быть использован (разработчиками библиотеки классов) для обеспечения некоторого базового поведения класса.
Например, убедитесь, что строка имеет неизменное поведение
Класс строки в java помечен как финальный, а в c # - как запечатанный.
Все строки являются неизменяемыми, и это поведение нельзя изменить.

0 голосов
/ 08 февраля 2009

Последний класс - это класс, который не может быть разделен на подклассы, поэтому все, что вы не хотите создавать производные. Например, в Java класс Math является окончательным, поскольку Java не хочет, чтобы вы могли переопределить, что означает абсолютное значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...