Есть ли какая-то особая причина, по которой я должен объявлять класс или метод final в повседневном программировании (в Интернете или в другом случае)? Пожалуйста, предоставьте реальный пример, где он должен использоваться.
Кстати, я спрашиваю, потому что я пытаюсь выбрать ключевое слово «неясное» и освоить его .
Это мешает другим программистам делать вещи с вашими классами, которые вы не собираетесь им делать. Поэтому вместо того, чтобы комментировать «не использовать этот класс для выполнения XXX», вы можете его спроектировать таким образом, чтобы у них не возникало соблазна переопределить его и оскорбить его таким образом.
Изменить : поскольку запрос запрашивается, я опишу случай, когда вы можете найти это ключевое слово под рукой … скажем, у вас есть класс, который определяет, как два объекта могут взаимодействовать друг с другом, скажем, с прослушивателем и уведомителем. Класс слушателя должен, очевидно, разрешать наследование, но вы можете сделать окончательный класс notifier таким, чтобы его можно было использовать в отношении «has-a». Таким образом, вы можете сделать некоторые предположения из ваших объектов-слушателей о характере сообщений, которые они получают.
В противном случае можно было бы наследовать от этого класса, делать всевозможные сумасшедшие вещи, такие как распространение сообщений и т. Д. Если вы не хотите, чтобы другие программисты это делали, вы могли бы сделать класс окончательным. Кроме того, это может иметь больший смысл в широко используемом публичном API, так как это позволяет другим программистам легко понять, какие классы подходят для подкласса.
Другой пример – скажем, что у вас есть потоковый процессор на основе буфера, и внутри вашего метода read () / write () вы сохраняете некоторые данные о текущем состоянии вашего объекта (т. Е. Текущий байт или что-то еще). Невозможно гарантировать, что кто-либо, подклассифицирующий этот класс, будет ссылаться на методы супер в процессе обработки, – и поскольку такой класс, вероятно, содержит только несколько методов, лучше просто сделать все окончательное вместо каждого метода. Это снова заставляет людей использовать класс «has-a», а не «is-a», и, таким образом, может контролировать, как вы ожидаете, что код будет выполнен.
Я согласен с вами в том, что создание финала всего класса – это, вероятно, то, что вам нужно было бы сделать один раз в синей луне, но приятно, что PHP имеет эту возможность, если вы решите использовать его.
«Enforce Composition over Inheritance» делает это довольно лаконично. Вы гарантируете определенное поведение вашего класса, которое ничто иное не может помешать, что, как поясняется в следующем разделе, также может иметь преимущества безопасности.
Некоторые люди утверждают, что вы должны объявить все классы окончательными, если вы специально не собираетесь разрешать и изучали последствия полиморфного расширения. Я склонен чувствовать, что это подразумевает много недоверия к тому, кто еще работает с вашим кодом, но, к сожалению, иногда это оправдано.
На многих языках объявление класса как окончательного также обеспечивает преимущества оптимизации, поскольку ему не нужно искать таблицу virt для методов.
Если вы хотите применить намерение класса и намерение таково, что оно не имеет смысла для подкласса, тогда используйте final; в противном случае нет существенного преимущества.
В общем, это всего лишь механизм обеспечения намерения.
Последний класс – это класс, который нельзя подклассифицировать, поэтому все, что вы не хотите создавать производные. Например, в Java класс Math является окончательным, поскольку Java не хочет, чтобы вы могли переопределить значение Absolute.
final (и запечатанный в c #) может использоваться (разработчиками библиотеки классов) для обеспечения некоторого базового поведения класса.
Например, убедитесь, что строка имеет неизменяемое поведение
Класс string в java отмечен как final, а в c # он отмечен как запечатанный.
Все строки неизменны и это поведение не может быть изменено.