◽
【SOLID原則】リスコフの置換原則とは何か
リスコフの置換原則
リスコフの置換原則は、LSP(Liskov Substitution Principle)とも呼ばれます。
SOLID原則のLにあたる部分です。
リスコフの置換原則は、サブタイプは、常にその基本型に置き換えることができるという原則です。
つまり、あるクラスを利用している場所に、そのクラスのサブクラスを置き換えても、プログラム全体の動作に影響がないようにすることが重要です。
すなわち以下の挙動にすべきということです。
- 子クラスでオーバーライドしたメソッドは、親クラスのメソッドと同様の引数を取り、同じ型の返り値を返さなければいけない。
たとえば、以下例ではリスコフの置換原則に違反しています
悪いコード(原則に反している)
class Rectangle {
constructor(public width: number, public height: number) {}
area(): number {
return this.width * this.height;
}
}
class Square extends Rectangle {
constructor(public size: number) {
super(size, size);
}
}
function printArea(rectangle: Rectangle) {
console.log(rectangle.area());
}
const rectangle = new Rectangle(10, 5);
const square = new Square(10);
printArea(rectangle); // 50
printArea(square); // 100
この例では、SquareクラスがRectangleクラスを継承していますが、Squareクラスには新しいプロパティであるsizeがあります。そのため、SquareクラスのインスタンスをRectangleクラスのインスタンスとして扱うことができません。
良いコード例(原則に則している)
これを解決するためには、SquareクラスをRectangleクラスから分離することができます。例えば、以下のようにすることができます。
abstract class Shape {
abstract area(): number;
}
class Rectangle extends Shape {
constructor(public width: number, public height: number) {
super();
}
area(): number {
return this.width * this.height;
}
}
class Square extends Shape {
constructor(public size: number) {
super();
}
area(): number {
return this.size ** 2;
}
}
function printArea(shape: Shape) {
console.log(shape.area());
}
const rectangle = new Rectangle(10, 5);
const square = new Square(10);
printArea(rectangle); // 50
printArea(square); // 100
このようにすることで、SquareクラスのインスタンスをRectangleクラスのインスタンスとして扱うことができます。つまり、リスコフの置換原則に違反していないということになります。
Discussion