좋은 객체 지향 설계 원칙중 하나인 OCP 원칙은 다형성인 인터페이스, 추상 클래스 등을 이용하여 준수할 수 있다. 이때 구현 VS 상속을 확실히 구분하여 언제 무엇을 사용하는 것이 좋을지에 대해서 감을 잡아보자.
OCP 는 코드 기능의 확장에는 열려 있고, 코드 수정시 최대한 기존의 코드의 변경을 줄이는 것이다.
추상 클래스는 왜 만들어졌을까? 본격적인 논의 전에 아래의 그림을 살펴보자.

Animal 의 sound 메서드를 3개의 자식 클래스가 상속받고 있다. 그런데 Animal 클래스가 생성하여 활용하는 것이 의미가 있을까?Animal animal = new Animal(); //이거 쓸 수 있어??
Animal 은 생성 용도가 아닌, 상속 용도로만 활용하는 클래스 라는 것을 알려주기 위해서 추상 클래스 개념이 도입된 것이다.public abstract class Animal{
public void sound() {print("동물이 웁니다.")} //상속 기능 제공
public abstract void move(); //모든 자식 클래스가 의무적으로 오버라이딩 해야함
}
//순수 추상 클래스
public abstract class AbstractAnimal {
public abstract void sound();
public abstract void move();
}
//인터페이스
public interface InterfaceAnimal {
void sound();
void move();
}
public abstract 키워드를 생략할 수 있어서 간편하다.public interface InterfaceA {
void methodA();
void methodCommon(); //공통 메서드임
}
public interface InterfaceB {
void methodB();
void methodCommon(); //공통 메서드임
}
public class Child implements InterfaceA, InterfaceB{
@Override
public void methodA(){print("Child.methodA")}
@Override
public void methodA(){print("Child.methodB")}
@Override
public void methodCommmon(){print("child.methodCommon")} //하나만 구현
}
Interface a = new Child();
a.methodCommon();
//a.methodB(); //요고는 안됨 InterfaceB를 통해서 접근

부모 클래스의 기능을 자식이 물려받을 때는 상속, 인터페이스는 구현한다는 표현을 한다. 이들을 구분하는 기준은 부모의 기능을 물려주는지에 대한 여부이다. 추상클래스는 자식 클래스에게 본인의 기능을 물려줄 수 있다. 반면에 인터페이스는 구현해야 되는 메서드를 강제한다.