Menu
Coddy logo textTech

트레이트 소개

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

PHP는 단일 상속만을 지원합니다 - 하나의 클래스는 오직 하나의 부모 클래스만 확장할 수 있습니다. 하지만 서로 관련이 없는 여러 클래스 간에 기능을 공유해야 한다면 어떻게 해야 할까요? 이럴 때 traits가 등장합니다.

트레이트(trait)는 여러 클래스에 삽입할 수 있는 메서드와 속성을 정의할 수 있게 해주는 코드 재사용 메커니즘입니다. 트레이트를 언어 수준에서의 복사-붙여넣기라고 생각하세요. 트레이트의 코드는 그것을 사용하는 클래스의 일부가 됩니다.

<?php
trait Timestampable {
    private string $createdAt;
    
    public function setCreatedAt(): void {
        $this->createdAt = date('Y-m-d H:i:s');
    }
    
    public function getCreatedAt(): string {
        return $this->createdAt;
    }
}

class Article {
    use Timestampable;
    
    public function __construct(public string $title) {
        $this->setCreatedAt();
    }
}

$article = new Article("PHP Traits");
echo $article->getCreatedAt();

클래스 내부의 use 키워드는 트레이트(trait)의 멤버들을 가져옵니다. 이제 Article은 마치 클래스에 직접 정의된 것처럼 setCreatedAt()getCreatedAt()에 접근할 수 있습니다.

동일한 trait은 완전히 서로 관련이 없는 클래스들 — Comment 클래스, User 클래스 또는 타임스탬프 기능이 필요한 다른 모든 클래스에서 사용될 수 있습니다. 이는 클래스 계층 구조 전반에 걸쳐 수평적인 코드 공유를 가능하게 함으로써 단일 상속의 제약을 해결합니다.

challenge icon

챌린지

쉬움

트레이트(trait)를 사용하여 서로 관련 없는 클래스 간에 기능을 공유하는 방법을 보여주는 간단한 인사 시스템을 만들어 보겠습니다. 인사 기능을 제공하는 트레이트를 생성한 다음, 이를 완전히 다른 두 클래스에서 사용해 볼 것입니다.

코드는 세 개의 파일로 구성됩니다:

  • Greetable.php — 인사 기능을 제공하는 Greetable이라는 트레이트를 생성합니다. 이 트레이트는 다음을 포함해야 합니다:
    • private 속성 $greeting (string)
    • 인사 메시지를 저장하는 setGreeting(string $greeting) 메서드
    • 인사 메시지를 반환하는 greet() 메서드
  • Person.phpGreetable 트레이트를 사용하는 Person 클래스를 생성합니다. 트레이트 파일을 포함(include)하고 생성자 프로모션(constructor promotion)을 사용하여 public $name 속성을 정의하세요. 생성자에서 setGreeting()을 호출하여 인사를 "Hello, I'm [name]"으로 설정합니다.
  • Robot.php — 역시 Greetable 트레이트를 사용하는 Robot 클래스를 생성합니다. 트레이트 파일을 포함하고 생성자 프로모션을 사용하여 public $model 속성을 정의하세요. 생성자에서 setGreeting()을 호출하여 인사를 "Beep boop, I am model [model]"으로 설정합니다.

main.php에서 두 클래스 파일을 모두 포함합니다. 사람의 이름과 로봇의 모델 번호라는 두 개의 입력을 받게 됩니다. 두 클래스의 인스턴스를 생성하고 각각의 인사를 별도의 줄에 출력하세요.

이것은 트레이트의 강력함을 보여줍니다. PersonRobot은 공통 부모가 없는 완전히 무관한 클래스이지만, 트레이트를 통해 동일한 인사 기능을 얻게 됩니다. 각 클래스는 해당 기능을 자신만의 방식으로 커스터마이징하여 사용합니다.

치트 시트

트레이트(trait)는 여러 관련 없는 클래스 간에 메서드와 속성을 공유할 수 있게 해주는 코드 재사용 메커니즘으로, PHP의 단일 상속 제한을 해결합니다.

trait 키워드를 사용하여 트레이트를 정의합니다:

<?php
trait Timestampable {
    private string $createdAt;
    
    public function setCreatedAt(): void {
        $this->createdAt = date('Y-m-d H:i:s');
    }
    
    public function getCreatedAt(): string {
        return $this->createdAt;
    }
}

use 키워드를 사용하여 클래스에서 트레이트를 사용합니다:

class Article {
    use Timestampable;
    
    public function __construct(public string $title) {
        $this->setCreatedAt();
    }
}

트레이트의 메서드와 속성은 마치 클래스 내에 직접 정의된 것처럼 클래스의 일부가 됩니다. 서로 관련 없는 여러 클래스가 동일한 트레이트를 사용하여 클래스 계층 구조 전체에서 기능을 수평적으로 공유할 수 있습니다.

직접 해보기

<?php

require_once 'Person.php';
require_once 'Robot.php';

// 입력 읽기
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));

// TODO: 주어진 이름으로 Person 인스턴스 생성
// TODO: 주어진 모델로 Robot 인스턴스 생성
// TODO: Person의 인사말 출력
// TODO: Robot의 인사말 출력 (새 줄에)

?>
quiz icon실력 점검

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

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