리스코프 치환 원칙(Liskov substitutaion principle)
리스코프는 해당 원칙을 만든 사람의 이름이다.
- 파생 클래스는 기본 클래스를 대체할 수 있어야 함
- 하위클래스를 강력하고 유연하게 만드는 원칙
- OOP의 상속을 사용하면 하위 클래스를 통해 기능을 추가할 수 있음
- 그러나, 주의하지 않으면 불필요한 복잡성이 발생
- 서브클래싱 할 때 기능을 제거하는 경우 리스코프치환원칙 위배
- 추상화(abstractiuon)를 단순하게 유지
- 하위 클래스에는 기본 클래스의 퍼블릭 멤버 존재
- 상속(inheritance)보다는 구성(composition)
- 클래스 계층 구조를 설정하기 전에 클래스 API를 고려
- 현실의 분류가 항상 클래스 계층 구조로 변환되는 것은 아님
- Ex: Car와 Train이 별도의 상위 클래스에서 상속받는 것이 더 합리적
public class Vehicle
{
public float speed = 100;
public Vector3 direction;
public void GoForward() {}
public void Reverse() {}
// 이럴 경우 기차에서는 TurnRight()와 TurnLeft()를 사용하지 않는다
public void TurnRight() {}
public void TurnLeft() {}
}
다음 코드처럼 리스코브 치환 원칙을 적용해보자
public interface ITurnable
{
public void TurnRight();
public void TurnLeft();
}
public interface IMoveable
{
public void GoForward();
public void Reverse();
}
// 자동차는 앞뒤로 이동, 회전 둘다 부여
public class RoadVehicle : IMoveable, ITurnable
{
public float speed = 100f;
public float turnSpeed = 5f;
public virtual void GoForward() {}
public virtual void Reverse() {}
public virtual void TrunLeft() {}
public virtual void TrunRight() {}
}
// 열차는 앞뒤로 이동만 적용
public class RailVehicle : IMoveable
{
public float speed = 100;
public virtual void GoForward() {}
public virtual void Reverse() {}
}