Trait 충돌 해결
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 53번째.
두 트레이트가 같은 이름의 method를 정의하면 PHP는 치명적인 오류를 발생시킵니다. insteadof 및 as 연산자를 사용하여 이 conflict를 처리하는 방법을 PHP에 명시적으로 알려야 합니다.
<?php
trait FileLogger {
public function log(string $message): void {
echo "File: $message";
}
}
trait DatabaseLogger {
public function log(string $message): void {
echo "DB: $message";
}
}
class Application {
use FileLogger, DatabaseLogger {
FileLogger::log insteadof DatabaseLogger;
DatabaseLogger::log as logToDatabase;
}
}
$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");
출력:
File: Error occurred
DB: Error occurredinsteadof 연산자는 충돌이 발생했을 때 사용할 트레이트의 method를 선택합니다. 이 예제에서는 FileLogger::log가 우선되어 default log() method가 됩니다. as 연산자는 alias를 생성하여 다른 트레이트의 method에 다른 이름으로 접근할 수 있게 합니다.
as를 사용하여 메서드의 가시성을 변경할 수도 있습니다:
<?php
trait Greeting {
public function sayHello(): void {
echo "Hello!";
}
}
class Person {
use Greeting {
sayHello as private;
}
}
이렇게 하면 트레이트에서는 public이더라도 sayHello()가 Person 클래스 내에서 private이 됩니다. 충돌 해결을 사용하면 트레이트 메서드가 클래스에 통합되는 방식을 세밀하게 제어할 수 있습니다.
챌린지
쉬움서로 다른 채널이 메시지를 보낼 수 있지만, 여러 트레이트가 동일한 method 이름을 제공할 때 충돌을 resolve해야 하는 notification 시스템을 만들어 봅시다.
코드를 네 개의 파일로 구성합니다:
EmailNotifier.php:EmailNotifier이라는 트레이트를 Create하고,"Email: [message]"를 반환하는notify(string $message)method를 만듭니다.SmsNotifier.php:SmsNotifier라는 트레이트를 Create하고,"SMS: [message]"를 반환하는notify(string $message)method를 만듭니다.AlertService.php: both 트레이트를 사용하는AlertServiceclass를 Create합니다. 두 트레이트 모두notify()method를 have 있으므로 이 conflict를 resolve해야 합니다:EmailNotifier::notify를 기본notify()method로 사용합니다.SmsNotifier::notifymethod에 대해notifyBySmsalias를 Create합니다.
notifyAll(string $message)method를 추가합니다.main.php: 필요한 모든 파일을 포함하고AlertServiceinstance를 Create합니다. 하나의 input, 즉 메시지 string을 받습니다. 다음 세 줄을 Print합니다:- 메시지와 함께
notify()를 calling한 결과 - 메시지와 함께
notifyBySms()를 calling한 결과 - 메시지와 함께
notifyAll()을 calling한 결과
- 메시지와 함께
이 예제는 이름 충돌이 발생했을 때 insteadof가 어떤 트레이트의 method가 우선할지 resolve하는 방법과, as를 사용하면 다른 트레이트의 method에 다른 이름으로 계속 액세스할 수 있는 방법을 보여 줍니다.
직접 해보기
<?php
require_once 'AlertService.php';
// 입력 읽기
$message = trim(fgets(STDIN));
// TODO: AlertService 인스턴스 생성
// TODO: message와 함께 notify()를 호출한 결과 출력
// TODO: message와 함께 notifyBySms()를 호출한 결과 출력
// TODO: message와 함께 notifyAll()를 호출한 결과 출력
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러