IT
PHP abstract (추상 클래스와 추상 메서드)
1. 추상 클래스 (abstract class)
-
abstract 키워드를 사용하여 선언합니다.
-
직접 new로 인스턴스화할 수 없습니다.
-
추상 메서드(구현이 없는 메서드)와 구체 메서드(일반 메서드)를 혼합할 수 있습니다.
-
상속받는 자식 클래스는 추상 메서드를 반드시 구현해야 합니다.
예제
abstract class Animal {
// 추상 메서드 (자식이 반드시 구현해야 함)
abstract public function makeSound(): void;
// 구체 메서드 (공통 동작 제공)
public function eat(): void {
echo "먹는 중...\n";
}
}
class Dog extends Animal {
public function makeSound(): void {
echo "멍멍\n";
}
}
class Cat extends Animal {
public function makeSound(): void {
echo "야옹\n";
}
}
$dog = new Dog();
$dog->makeSound(); // 멍멍
$dog->eat(); // 먹는 중...
2. 추상 메서드 (abstract method)
-
메서드의 시그니처(이름, 매개변수, 반환 타입)만 정의하고 본문은 없습니다.
-
자식 클래스가 반드시 구현(override) 해야 합니다.
-
접근 제어자는 public 또는 protected만 허용됩니다. (private은 불가능)
문법
abstract public function process(string $data): bool;
3. 특징
-
상속 전용
-
추상 클래스는 단독으로 객체 생성 불가.
-
반드시 extends 해서 사용해야 합니다.
-
공통 로직 + 구현 강제
-
여러 자식 클래스가 공유해야 하는 코드를 추상 클래스에 넣을 수 있음.
-
동시에 추상 메서드로 “이 메서드는 꼭 구현해야 한다”는 계약을 강제.
-
다중 상속 불가
-
클래스는 하나의 추상 클래스만 상속받을 수 있습니다. (PHP는 다중 클래스 상속을 지원하지 않음)
-
대신 인터페이스 다중 구현 + 추상 클래스 상속 조합이 흔히 사용됩니다.
4. 추상 클래스와 인터페이스 차이점
구분
Abstract class
Interface
목적
기본 구조 + 강제 구현
계약(Contract)만 정의
메서드
추상 + 구체 혼합 가능
모든 메서드는 public, 구현 없음
프로퍼티
인스턴스 변수, 상태 보관 가능
불가 (PHP 8.1에서 제한적으로 readonly 프로퍼티 지원)
상속/구현
클래스 단일 상속만 가능
여러 인터페이스 다중 구현 가능
공통 로직
가능 (메서드 구현, 멤버 변수 활용)
불가능
5. 실무 예시
(1) 템플릿 메서드 패턴
abstract class Report {
// 템플릿 메서드: 실행 순서 정의
public function generate(): void {
$this->header();
$this->body();
$this->footer();
}
abstract protected function header(): void;
abstract protected function body(): void;
abstract protected function footer(): void;
}
class HtmlReport extends Report {
protected function header(): void { echo "<h1>HTML Header</h1>"; }
protected function body(): void { echo "<p>HTML Body</p>"; }
protected function footer(): void { echo "<footer>HTML Footer</footer>"; }
}
class TextReport extends Report {
protected function header(): void { echo "TEXT Header\n"; }
protected function body(): void { echo "TEXT Body\n"; }
protected function footer(): void { echo "TEXT Footer\n"; }
}
$r = new HtmlReport();
$r->generate();
-
Report 클래스는 전체 실행 흐름(generate) 을 제공하고,
-
세부 부분(header, body, footer)은 자식 클래스에 강제합니다.
(2) 공통 동작 강제화
예: 모든 Controller 클래스는 handle() 메서드를 반드시 가져야 함.
abstract class Controller {
abstract public function handle(Request $req, Response $res): void;
protected function render(string $view): void {
include $view;
}
}
6. 베스트 프랙티스
-
공통 동작은 추상 클래스, 계약은 인터페이스
-
여러 클래스가 같은 동작을 공유해야 하면 abstract class
-
단순히 “이 메서드를 반드시 제공해야 한다”라면 interface
-
하나의 클래스 계층 구조를 설계할 때 사용
-
추상 클래스는 상속 계층의 루트 역할을 할 때 적합.
-
코드 중복 제거
-
자식 클래스에 반복되는 로직은 추상 클래스에서 제공.
결론
-
abstract class는 인스턴스화 불가한 기본 설계도로, 공통 코드와 구현 강제 기능을 동시에 제공한다.
-
인터페이스보다 더 구체적인 기본 구현이 필요할 때 추상 클래스를 사용한다.
-
실무에서는 인터페이스(규약) + 추상 클래스(공통 로직) + 구현 클래스(세부 구현) 패턴으로 많이 활용된다.
댓글
아직 댓글이 없습니다.
로그인 후 댓글을 남길 수 있습니다.