"추상 클래스는 반쯤 만든 객체가 아니라, 하위 클래스가 완성해야 할 계약이야."
직접 만들 수 없는 기반 클래스
abstract class Shape는 new Shape()로 직접 인스턴스를 만들 수 없어. 대신 공통 필드와 구현된 메서드를 제공하면서, abstract area(): number처럼 하위 클래스가 반드시 채울 멤버를 선언해. 계약과 재사용할 구현을 한곳에 둘 수 있다는 점이 인터페이스와 달라.
하위 클래스는 모든 추상 멤버를 구현해야 하고 타입도 부모 선언과 호환되어야 해. 구현을 빼먹으면 컴파일러가 인스턴스 생성 전에 잡아 주므로, 런타임의 '이 메서드는 아직 구현되지 않았다' 오류를 줄일 수 있지.
인터페이스와 무엇이 다를까
인터페이스는 객체가 갖춰야 할 모양만 표현하고 여러 계약을 자유롭게 조합하기 좋아. 추상 클래스는 생성 과정, 보호된 상태, 기본 동작을 함께 공유할 때 의미가 있어. 구현 공유가 필요하지 않다면 더 가벼운 인터페이스가 보통 낫다.
TypeScript는 클래스 하나만 extends할 수 있지만 인터페이스는 여러 개 implements할 수 있어. '같은 종류'의 수명 주기와 불변식이 있는 계층이라면 추상 클래스, 서로 독립적인 능력을 붙이는 문제라면 인터페이스를 먼저 생각해 봐.
추상 클래스는 공유할 구현과 강제할 빈칸이 둘 다 있을 때 선택해. 구현 없는 계약만 필요하면 인터페이스가 더 단순하고 유연해.