Trait와 상속 비교
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 55번째.
이제 trait가 어떻게 작동하는지 이해했으므로, trait와 Inheritance 중 언제 무엇을 사용해야 하는지 명확히 알아보겠습니다. 둘 다 코드 재사용을 가능하게 하지만, 서로 다른 목적과 뚜렷한 특성을 가집니다.
Inheritance는 "is-a" 관계를 설정합니다. Dog 클래스가 Animal을 확장한다는 것은 개가 동물이라는 것을 의미합니다. 자식 클래스는 부모의 정체성을 상속하며 부모 타입이 예상되는 모든 곳에서 사용할 수 있습니다.
트레이트는 "has-a" 기능을 제공합니다. 클래스가 Loggable 트레이트를 사용하면 has 로깅 기능을 가지지만, 로거가 되는 것은 아닙니다. 트레이트는 클래스의 본질적인 정체성을 바꾸지 않고 동작을 추가합니다.
<?php
// 상속: Dog IS an Animal
class Animal {
public function breathe(): void {
echo "Breathing";
}
}
class Dog extends Animal {
public function bark(): void {
echo "Woof!";
}
}
// 트레이트: Dog HAS 로깅 기능
trait Loggable {
public function log(string $msg): void {
echo "Log: $msg";
}
}
class Cat extends Animal {
use Loggable;
}
기억해야 할 주요 차이점:
| 측면 | Inheritance | 트레이트 |
|---|---|---|
| 관계 | is-a | has-a capability |
| 제한 | 단일 parent만 허용 | 여러 트레이트 허용 |
| 형식 검사 | instanceof와 함께 작동 | 형식 정체성 없음 |
| 적합한 경우 | 계층적 관계 | 서로 관련 없는 클래스 간 공유 동작 |
클래스가 공통된 정체성을 공유할 때는 상속을 사용하세요. 서로 관련 없는 클래스에 같은 기능이 필요하지만 동일한 계층 구조에 속하지 않을 때는 트레이트를 사용하세요.
챌린지
쉬움상속과 trait를 언제 사용해야 하는지 보여 주는 vehicle system을 만들어 보겠습니다. 상속을 통해 공통된 정체성을 공유하는 vehicle 계층 구조를 만들고, trait를 통해 여러 곳에 걸쳐 적용되는 capability를 추가합니다.
코드를 네 개의 파일로 구성합니다:
Trackable.php: GPS tracking capability를 제공하는Trackabletrait를 Create합니다. trait에는 다음이 있어야 합니다:- private property
$location(string) - current location을 저장하는
setLocation(string $location)method "Location: [location]"을 반환하는getLocation()method
- private property
Vehicle.php: "is-a" relationship을 establish하는 baseVehicleclass를 Create합니다. trait file을 Include합니다. constructor promotion을 사용하여 protected$brandproperty를 define합니다."Vehicle: [brand]"를 반환하는describe()method를 Add합니다. fleet의 모든 vehicle이 GPS를 가지므로 이 class는Trackabletrait를 사용해야 합니다.Car.php:Vehicle을 extends하는Carclass를 Create합니다. Vehicle file을 Include합니다. constructor promotion을 사용하여 brand와 private$doors(integer) property를 accept합니다. brand와 함께 parent constructor를 call합니다.describe()method를 Override하여"Car: [brand] with [doors] doors"를 반환합니다.main.php: Car file을 Include합니다. 세 가지 inputs를 받습니다: brand name, doors의 수, location string입니다.Carinstance를 Create하고 location을 설정한 다음, 두 줄을 print합니다:describe()를 call한 결과getLocation()을 call한 결과
여기서 Inheritance와 trait가 어떻게 함께 작동하는지 확인해 보세요. Car is a Vehicle입니다 (Inheritance가 identity를 establish합니다). 반면 Vehicle has tracking capability를 가집니다 (trait가 behavior를 Add합니다). 무언가가 vehicle인지 확인하기 위해 instanceof Vehicle을 사용할 수 있지만, 확인할 수 있는 "Trackable" type은 없습니다. 이것이 이 두 접근 방식의 핵심적인 차이입니다.
직접 해보기
<?php
// 메인 파일 - Car 인스턴스 생성 및 테스트
// TODO: Car.php 파일 포함
// 입력 읽기
$brand = trim(fgets(STDIN));
$doors = intval(trim(fgets(STDIN)));
$location = trim(fgets(STDIN));
// TODO: brand와 doors로 Car 인스턴스 생성
// TODO: 자동차의 location 설정
// TODO: describe() 결과 출력
// TODO: getLocation() 결과 출력
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러