IMG-LOGO
공지사항 :

PHP  abstract  (추상 클래스와 추상 메서드)

lmkfox - 2025-09-15 06:33:54 5 Views 0 Comment

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. 특징

  1. 상속 전용

    • 추상 클래스는 단독으로 객체 생성 불가.

    • 반드시 extends 해서 사용해야 합니다.

  2. 공통 로직 + 구현 강제

    • 여러 자식 클래스가 공유해야 하는 코드를 추상 클래스에 넣을 수 있음.

    • 동시에 추상 메서드로 “이 메서드는 꼭 구현해야 한다”는 계약을 강제.

  3. 다중 상속 불가

    • 클래스는 하나의 추상 클래스만 상속받을 수 있습니다. (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. 베스트 프랙티스

  1. 공통 동작은 추상 클래스, 계약은 인터페이스

    • 여러 클래스가 같은 동작을 공유해야 하면 abstract class

    • 단순히 “이 메서드를 반드시 제공해야 한다”라면 interface

  2. 하나의 클래스 계층 구조를 설계할 때 사용

    • 추상 클래스는 상속 계층의 루트 역할을 할 때 적합.

  3. 코드 중복 제거

    • 자식 클래스에 반복되는 로직은 추상 클래스에서 제공.


결론

  • abstract class는 인스턴스화 불가한 기본 설계도로, 공통 코드와 구현 강제 기능을 동시에 제공한다.

  • 인터페이스보다 더 구체적인 기본 구현이 필요할 때 추상 클래스를 사용한다.

  • 실무에서는 인터페이스(규약) + 추상 클래스(공통 로직) + 구현 클래스(세부 구현) 패턴으로 많이 활용된다.


댓글