Definição 1: Se para cada objeto O1 do tipo T1, houver um objeto O2 do tipo T2, para que todos os programas p definidos em T1 não tenham alteração no comportamento quando todos os objetos O1 são substituídos por O2, o tipo T2 é um subtipo do tipo T1.
Definição 2: Todos os lugares referentes às classes base devem poder usar objetos de suas subclasses de forma transparente.
A origem do problema: existe uma função P1, que é concluída pela classe A. Agora é necessário expandir a função P1, e a função estendida é P, onde P consiste na função original p1 e na nova função p2. A nova função P é concluída pela subclasse B da classe A. A subclasse B pode fazer com que a função original P1 falhe ao concluir a nova função P2.
Solução: Ao usar a herança, siga o princípio da substituição de Richter. Quando a Classe B herda a classe A, além de adicionar novos métodos para concluir a nova função P2, tente não reescrever os métodos da classe A dos pais A e tente não sobrecarregar os métodos da classe pai A.
A herança contém o significado de: qualquer método que tenha sido implementado na classe pai (em relação aos métodos abstratos) está na verdade uma série de especificações e contratos. Embora não force todas as subclasses a cumprir com esses contratos, se a subclasse modificar arbitrariamente esses métodos não abstratos, ele danificará todo o sistema de herança. O princípio da substituição de Lizur expressa esse significado.
A herança, como uma das três principais características orientadas a objetos, traz grande conveniência para a programação, mas também traz desvantagens. Por exemplo, o uso da herança trará invasão ao programa, a portabilidade do programa reduzirá e aumentará o acoplamento entre os objetos. Se uma classe for herdada por outras classes, quando essa classe precisar ser modificada, todas as subclasses devem ser levadas em consideração. Depois que a classe pai é modificada, todas as funções envolvendo subclasses podem falhar.
exemplo:
classe pública retângulo {int width; int altura; retângulo público (int w, int h) {width = w; altura = h; } public int getarea () {return width*altura; }} classe pública quadrada estende o retângulo {public square (int w, int h) {super (w, h); } public int getarea () {return width*width; }} classe pública teste {public static void main (string [] args) {retângulo retângulo = novo retângulo (10, 20); // retângulo quadrado = novo quadrado (10, 20); System.out.println ("Area:"+Rectangle.getarea ()); }}
Se substituirmos o retângulo da classe retângulo pelo quadrado da classe quadrada, a área que encontramos está incorreta porque reescrevemos o método getarea da classe pai ao herdar. Isso viola o princípio da substituição lissiana.
Obviamente, aqui está apenas um exemplo, não modificaremos isso em projetos reais.
Resumir:
1. Tente não reescrever o método da classe pai, mas adicione seus próprios métodos exclusivos.
2. Embora a herança traga grande conveniência para a programação, ela também traz desvantagens. Se uma classe for herdada por outras classes, quando essa classe precisar ser modificada, todas as subclasses devem ser levadas em consideração. Depois que a classe pai é modificada, todas as funções envolvendo subclasses podem ter erros.