Принцип замены Рича, OCP, как принцип высокого уровня OO, выступает за использование «абстракции» и «полиморфизма», чтобы изменить статическую структуру в конструкции в динамическую структуру для поддержания корпуса дизайна. «Аннотация» - это функция, предоставленная языком. «Полиморфизм» реализован унаследованной семантикой.
Принцип замены Рихтера содержит следующие 4 значения:
Теперь мы можем объяснить вышеупомянутые четыре значения.
Подклассы могут реализовать абстрактные методы родительского класса, но не могут переопределить неабстроктные методы родительского класса.
Когда мы разрабатываем системы, мы часто разрабатываем интерфейсы или абстрактные классы, а затем подклассы реализуют абстрактные методы. Принцип замены Рихтера на самом деле используется здесь. Легко понять, что подклассы могут реализовать абстрактный метод родительского класса. Фактически, подклассы должны полностью реализовать абстрактный метод родительского класса, даже если они пишут пустой метод, в противном случае они будут компилировать и сообщать об ошибке.
Ключевой момент принципа замены Рихтера заключается в том, что он не может охватывать неабстроктные методы родительского класса. Любой хорошо реализованный метод в родительском классе фактически устанавливает серию спецификаций и контрактов. Хотя это не заставляет все подклассы соответствовать этим спецификациям, если подкласс произвольно изменяет эти неабстрактные методы, это повредит всю систему наследования. Принцип замены Лизура выражает это значение.
В объектно-ориентированной дизайнерской идее, наследуя эту функцию приносит большое удобство для дизайна системы, но есть также некоторые риски, которые исходят из нее. Следующие примеры используются для иллюстрации риска наследования. Нам нужно завершить функцию вычитания двух чисел, а класс A отвечает за него.
класс A {public int func1 (int a, int b) {return ab; }} public class client {public static void main (string [] args) {a a = new a (); System.out.println ("100-50 ="+A.Func1 (100, 50)); System.out.println ("100-80 ="+A.Func1 (100, 80)); }} Результаты работы:
100-50 = 50100-80 = 20
Позже нам нужно добавить новую функцию: завершить добавление двух чисел, а затем суммировать ее 100, а класс B отвечает. То есть класс B должен выполнить две функции:
Два числа вычитают.
Добавьте два числа, а затем добавьте 100.
Поскольку класс А внедрил первую функцию, после того, как класс B наследил класс A, вам нужно только выполнить вторую функцию. Код заключается в следующем:
Класс B расширяет {public int func1 (int a, int b) {return a+b; } public int func2 (int a, int b) {return func1 (a, b) +100; }} public Class Client {public static void main (string [] args) {b b = new b (); System.out.println ("100-50 ="+b.func1 (100, 50)); System.out.println ("100-80 ="+b.func1 (100, 80)); System.out.println ("100+20+100 ="+b.func2 (100, 20)); }} После завершения класса B результат пробега:
100-50 = 150100-80 = 180100+20+100 = 220
Мы обнаружили, что функция вычитания, которая изначально работала, обычно имела ошибку. Причина в том, что когда класс B назвал метод, он случайно переписывает метод родительского класса, вызывая все коды, которые запускают функции вычитания, чтобы вызвать метод переписывания класса B, вызывая ошибки в исходной нормальной функции. В этом примере, после ссылки на функцию, выполненную базовым классом A и изменяющимся на подкласс B, произошло исключение. В реальном программировании мы часто выполняем новые функции, переписывая метод родительского класса. Хотя его просто писать, способность повторного использования всей системы наследования будет относительно плохой, особенно когда полиморфизм используется чаще, вероятность ошибок в работе программы очень высока. Если вам нужно переписать метод родительского класса, более распространенным подходом является: оригинальный класс родительского класса и детского класса наследуют более популярный базовый класс, удалите исходные отношения наследования и вместо этого используйте зависимость, агрегацию, комбинацию и другие отношения.