Menu
Coddy logo textTech

Trait의 추상 메서드

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 54번째.

트레이트는 바로 사용할 수 있는 메서드를 제공할 수 있지만, 때로는 트레이트를 사용하는 class가 특정 기능을 구현해야 합니다. 이때 트레이트의 abstract 메서드가 유용합니다. abstract 메서드는 사용하는 class가 충족해야 하는 계약을 정의합니다.

trait이 추상 메서드를 선언하면 해당 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!

trait는 sendNotification() 메서드를 제공하지만, 클래스에서 getEmail()을 구현해야 합니다. 이를 통해 trait가 공통 로직을 처리하고 클래스별 세부 사항은 구현하는 클래스에 위임하는 강력한 패턴이 만들어집니다.

class가 abstract method를 구현하지 않고 trait를 사용하면 PHP는 치명적 오류를 발생시킵니다. 이를 통해 trait가 특정 method의 존재에 안전하게 의존할 수 있으므로 코드가 더 예측 가능하고 유지 관리하기 쉬워집니다.

challenge icon

챌린지

쉬움

서로 다른 제품 유형이 최종 가격을 서로 다르게 계산하지만, abstract method가 있는 trait를 통해 공통 할인 로직을 공유하는 가격 시스템을 만들어 봅시다.

코드를 세 개의 파일로 구성합니다:

  • Discountable.php: 할인 기능을 제공하는 Discountable trait를 Create합니다. trait에는 다음이 있어야 합니다:
    • 이 trait를 사용하는 class가 Implement해야 하는 getBasePrice(): float abstract method
    • 기본 가격에 할인 percent를 applying한 후의 가격을 calculate하여 반환하는 applyDiscount(int $percent) method
    • 소수점 이하 2 places로 formatted된 문자열 "Final price: $[discounted_price]"를 반환하는 getFinalPrice(int $percent) method
    trait는 모든 할인 계산을 처리하지만, 기본 가격이 무엇인지는 각 class가 알려 주어야 합니다.
  • Product.php: Discountable trait를 사용하는 Product class를 Create합니다. trait 파일을 Include합니다. constructor promotion을 사용하여 private $name(string)과 private $price(float)를 Declare합니다. product의 price를 반환하도록 required getBasePrice() method를 Implement합니다.
  • main.php: Product 파일을 Include합니다. product name, price, discount percentage라는 세 개의 inputs를 받습니다. Product instance를 Create하고 두 줄을 Print합니다:
    • 소수점 이하 2 places로 formatted된 base price: "Base: $[price]"
    • discount percentage를 사용하여 getFinalPrice()를 calling한 result

이 pattern은 강력합니다. Discountable trait는 products, services, subscriptions 등 어떤 class에서든 사용할 수 있으며, 해당 class가 getBasePrice()를 Implement하기만 하면 됩니다. trait는 공유되는 discount logic을 제공하고, 각 class는 base price가 어디에서 오는지 define합니다.

직접 해보기

<?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()를 호출한 결과 출력

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 PHP 컴파일러