Насколько я знаю, речь идет о создании инвариантов.
В аналогичной ситуации, например, вы можете сделать ваши атрибуты открытыми, но тогда вы потеряете контроль над их значениями, потому что клиенты смогут изменять их напрямую, нарушая некоторые свойства, которые вы хотели бы сохранить. Таким образом, точно так же, как вы запрещаете клиентам доступ к некоторым (чаще всего) полям напрямую, чтобы поддерживать некоторый инвариант, вы также делаете свой класс / метод окончательным, чтобы поддерживать некоторый инвариант об этом.
Типичный пример, который я вижу, связан с неизменяемостью, которая может быть нарушена, если класс не является окончательным.
Проблема на самом деле не в том, что пользователь расширяет класс и использует его только в своей системе, живя со своим собственным "беспорядком", изолированным от всего остального. Настоящая проблема связана с тем фактом, что классы / методы / атрибуты / объекты / ... не существуют изолированно.
Скажем, у вас есть коллекция классов CC1, которая объединяется с какой-то целью, и один из этих классов CC1_A должен "производить" только неизменяемые объекты (или любой другой инвариант, который вы хотите). Затем вы продолжаете и расширяете CC1_A, делая CC2_AX (расширенный A в коллекции второго класса). Теперь вы можете использовать материал CC1, передавая CC2_AX, где требуется CC1_A. Тем не менее, CC1 был построен, предполагая, что объекты CC1_A являются неизменяемыми, а ваши объекты CC2_AX - нет (предположим, они не только для примера). Это может привести к серьезным проблемам в вашей программе. Такая проблема может возникнуть даже внутри класса. Например, методы CC1_A, вероятно, будут предполагать, что объекты CC1_A являются неизменяемыми, поэтому методы CC2_AX, полученные из CC1_A, могут потенциально завершиться сбоем, поскольку CC2_AX нарушает свойство неизменяемости.
В наших системах сегодня у нас много классов, и многое из того, что мы делаем, идет неявно. Поэтому мы не всегда думаем об инвариантах, которые хотели бы сохранить. Это не облегчает жизнь.
Кстати, некоторые другие инварианты включают в себя такие вещи, как:
- Метод сортировки должен быть стабильным.
- В методе используется <другой такой> алгоритм.
- Эта реализация списка должна использовать реализацию простого связанного списка, как описано .
Это продолжается и продолжается. Некоторые классы полезны только потому, что они поддерживают более сильные инварианты (например, использование определенного алгоритма), а расширение позволяет людям легко ломать подобные вещи. И причина, почему это все проблема, связана с тем, что эти вещи не живут в изоляции.