定義1:タイプT1の各オブジェクトO1にタイプT2のオブジェクトO2がある場合、T1で定義されたすべてのプログラムPがすべてのオブジェクトO1をO2に置き換えると動作に変化がありません。タイプT2はタイプT1のサブタイプです。
定義2:基本クラスを参照するすべての場所は、サブクラスのオブジェクトを透過的に使用できる必要があります。
問題の起源:関数P1があります。これはクラスAで完了します。これは、関数P1を拡張する必要があり、拡張機能はP1であり、Pは元の関数P1と新しい関数P2で構成されています。新しい関数Pは、クラスAのサブクラスBによって完了します。サブクラスBは、新しい関数P2の完了中に元の関数P1が失敗する可能性があります。
解決策:継承を使用する場合、リヒター交換の原則に従ってください。クラスBがクラスAを継承する場合、新しい機能P2を完了するための新しい方法を追加することに加えて、親クラスAの方法を書き換えないようにし、親クラスAの方法を過負荷にしないようにしてください。
継承には、次の意味が含まれています。親クラスで実装されている方法(抽象的方法と比較して)は、実際に一連の仕様と契約を設定することです。すべてのサブクラスがこれらの契約に準拠するように強制するわけではありませんが、サブクラスがこれらの非抽象的メソッドを任意に変更すると、継承システム全体が損傷します。リズル置換の原則は、この意味を表しています。
継承は、3つの主要なオブジェクト指向の機能の1つとして、プログラミングに大きな利便性をもたらしますが、不利な点ももたらします。たとえば、継承を使用すると、プログラムに侵襲性がもたらされ、プログラムの移植性が低下し、オブジェクト間の結合が増加します。クラスが他のクラスで継承されている場合、このクラスを変更する必要がある場合、すべてのサブクラスを考慮する必要があります。親クラスが変更された後、サブクラスを含むすべての機能が故障する可能性があります。
例:
public class rectangle {int width; int height; public rectangle(int w、int h){width = w;高さ= h; } public int getarea(){return width*height; }} public class Squareは長方形を拡張します{public Square(int w、int h){super(w、h); } public int getarea(){return width*width; }} public class test {public static void main(string [] args){rectangle rectangle = new rectangle(10、20); //正方形のrectangle = new Square(10、20); System.out.println( "area:"+rectangle.getarea()); }}
長方形クラスの長方形を正方形の正方形に置き換えると、継承するときに親クラスのgetarea法を書き直すため、見つけた領域が正しくありません。これは、リシアの代替の原則に違反しています。
もちろん、これは単なる例です。実際のプロジェクトでこれを変更することはありません。
要約:
1.親クラスの方法を書き直さないようにしてください。独自の方法を追加してください。
2。継承はプログラミングに大きな利便性をもたらしますが、それはまた、欠点をもたらします。クラスが他のクラスで継承されている場合、このクラスを変更する必要がある場合、すべてのサブクラスを考慮する必要があります。親クラスが変更された後、サブクラスを含むすべての関数にバグがある場合があります。