Trait 소개
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 51번째.
PHP는 단일 상속만 지원합니다. 즉, 하나의 class는 하나의 부모 class만 확장할 수 있습니다. 하지만 서로 관련이 없는 여러 class 간에 기능을 공유해야 한다면 어떻게 해야 할까요? 이럴 때 바로 트레이트가 사용됩니다.
trait는 코드를 재사용할 수 있게 해 주는 메커니즘으로, 여러 class에 삽입할 수 있는 method와 property를 define할 수 있습니다. trait를 언어 수준의 복사-붙여넣기라고 생각해 보세요. trait의 코드는 이를 사용하는 class의 일부가 됩니다.
<?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는 서로 전혀 관련이 없는 class에서도 사용할 수 있습니다. 예를 들어 Comment class, User class 또는 타임스탬프 기능이 필요한 다른 어떤 class에서도 사용할 수 있습니다. 이를 통해 class 계층 구조 전반에서 코드를 수평적으로 공유할 수 있으므로 단일 상속의 한계를 해결할 수 있습니다.
챌린지
쉬움서로 관련이 없는 class 간에 기능을 공유할 수 있도록 하는 trait의 작동 방식을 보여 주는 간단한 greeting 시스템을 만들어 보겠습니다. greeting 기능을 제공하는 trait를 만든 다음, 완전히 다른 두 class에서 사용합니다.
코드를 세 개의 파일로 구성합니다.
Greetable.php: greeting 기능을 제공하는Greetable이라는 trait를 Create합니다. trait에는 다음이 있어야 합니다.- private property
$greeting(string) - greeting message를 stores하는
setGreeting(string $greeting)method - greeting message를 returns하는
greet()method
- private property
Person.php:Greetabletrait를 사용하는Personclass를 Create합니다. trait file을 include하고 constructor promotion을 사용하여 public$nameproperty를 define합니다. constructor에서setGreeting()을 Call하여 greeting을"Hello, I'm [name]"으로 설정합니다.Robot.php: 역시Greetabletrait를 사용하는Robotclass를 Create합니다. trait file을 include하고 constructor promotion을 사용하여 public$modelproperty를 define합니다. constructor에서setGreeting()을 Call하여 greeting을"Beep boop, I am model [model]"으로 설정합니다.
main.php에서는 두 class file을 모두 include합니다. 두 가지 input, 즉 person의 name과 robot의 model number를 받습니다. 두 class의 instance를 Create하고 각각의 greeting을 별도의 줄에 Print합니다.
이는 trait의 강력한 기능을 보여 줍니다. Person과 Robot은 shared parent가 없는 완전히 unrelated class이지만, trait를 통해 동일한 greeting 기능을 모두 얻게 됩니다. 각 class는 자신만의 방식으로 해당 기능을 사용하는 방법을 customize합니다.
직접 해보기
<?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의 인사말 출력 (새 줄에)
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러