트레이트의 추상 메서드
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 54번째.
트레이트(Trait)는 즉시 사용할 수 있는 메서드를 제공할 수 있지만, 때로는 트레이트를 사용하는 클래스가 특정 기능을 구현해야 할 때가 있습니다. 이럴 때 트레이트의 추상 메서드(abstract methods in traits)가 유용합니다. 이는 사용하는 클래스가 반드시 충족해야 하는 계약을 정의합니다.
트레이트(trait)가 추상 메서드를 선언하면, 해당 트레이트를 사용하는 모든 클래스는 이를 반드시 구현해야 합니다:
<?php
trait Notifiable {
abstract public function getEmail(): string;
public function sendNotification(string $message): void {
echo "Sending to " . $this->getEmail() . ": $message";
}
}
class User {
use Notifiable;
public function __construct(private string $email) {}
public function getEmail(): string {
return $this->email;
}
}
$user = new User("john@example.com");
$user->sendNotification("Welcome!");
출력:
Sending to john@example.com: Welcome!이 트레이트는 sendNotification() 메서드를 제공하지만, 클래스에서 getEmail()이 구현되어야 합니다. 이는 트레이트가 공통 로직을 처리하면서 클래스별 세부 사항을 구현 클래스에 위임하는 강력한 패턴을 만듭니다.
만약 클래스가 추상 메서드를 구현하지 않고 트레이트를 사용하면, PHP는 치명적 오류(fatal error)를 발생시킵니다. 이는 트레이트가 특정 메서드의 존재에 안전하게 의존할 수 있도록 보장하여, 코드를 더 예측 가능하고 유지보수하기 쉽게 만들어 줍니다.
챌린지
쉬움서로 다른 제품 유형이 최종 가격을 다르게 계산하지만, 추상 메서드를 가진 trait을 통해 공통된 할인 로직을 공유하는 가격 책정 시스템을 구축해 보겠습니다.
코드는 세 개의 파일로 구성됩니다:
Discountable.php— 할인 기능을 제공하는Discountable이라는 trait을 생성합니다. 이 trait은 다음을 포함해야 합니다:- 이 trait을 사용하는 클래스가 반드시 구현해야 하는 추상 메서드
getBasePrice(): float - 기본 가격에 할인율을 적용한 후의 가격을 계산하여 반환하는
applyDiscount(int $percent)메서드 "Final price: $[discounted_price]"형식의 문자열(소수점 2자리까지 표시)을 반환하는getFinalPrice(int $percent)메서드
- 이 trait을 사용하는 클래스가 반드시 구현해야 하는 추상 메서드
Product.php—Discountabletrait을 사용하는Product클래스를 생성합니다. trait 파일을 포함(include)하세요. 생성자 프로모션(constructor promotion)을 사용하여 private$name(string)과 private$price(float)를 정의합니다. 제품의 가격을 반환하도록 필수 메서드인getBasePrice()를 구현합니다.main.php— Product 파일을 포함합니다. 제품 이름, 가격, 할인율이라는 세 가지 입력을 받게 됩니다.Product인스턴스를 생성하고 다음 두 줄을 출력합니다:"Base: $[price]"형식으로 포맷된 기본 가격 (소수점 2자리까지 표시)- 할인율을 인자로 하여
getFinalPrice()를 호출한 결과
이 패턴은 getBasePrice()를 구현하기만 하면 제품, 서비스, 구독 등 어떤 클래스에서도 Discountable trait을 사용할 수 있기 때문에 매우 강력합니다. trait은 공유된 할인 로직을 제공하고, 각 클래스는 기본 가격이 어디에서 오는지 정의합니다.
치트 시트
트레이트는 해당 트레이트를 사용하는 모든 클래스에서 반드시 구현해야 하는 추상 메서드(abstract methods)를 선언할 수 있습니다:
<?php
trait Notifiable {
abstract public function getEmail(): string;
public function sendNotification(string $message): void {
echo "Sending to " . $this->getEmail() . ": $message";
}
}
class User {
use Notifiable;
public function __construct(private string $email) {}
public function getEmail(): string {
return $this->email;
}
}
트레이트는 즉시 사용할 수 있는 메서드를 제공하는 동시에 클래스가 특정 기능을 구현하도록 요구합니다. 만약 클래스가 추상 메서드를 구현하지 않고 트레이트를 사용하면, PHP는 치명적 오류(fatal error)를 발생시킵니다.
이 패턴을 통해 트레이트는 공통 로직을 처리하고, 클래스별 세부 사항은 이를 구현하는 클래스에 위임할 수 있습니다.
직접 해보기
<?php
require_once 'Product.php';
// 입력 읽기
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$discountPercent = intval(trim(fgets(STDIN)));
// TODO: 이름과 가격으로 Product 인스턴스 생성
// TODO: "Base: $[price]" 형식으로 소수점 2자리까지 기본 가격 출력
// TODO: 할인율을 적용하여 getFinalPrice()를 호출한 결과 출력
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8매직 메서드
매직 메서드 소개__toString 및 __debugInfo__get, __set, __isset, __unset__call 및 __callStatic__clone 및 객체 복제__serialize 및 __unserialize요약 - 커스텀 컬렉션