지연 정적 바인딩
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 36번째.
부모 클래스에서 self::를 사용하면, 실제로 사용되는 클래스가 아니라 항상 해당 코드가 작성된 클래스를 가리킵니다. 이로 인해 상속에서 예상치 못한 동작이 발생할 수 있습니다. 지연 정적 바인딩은 static:: 키워드를 사용하여 이 문제를 해결합니다.
self::가 예상대로 작동하지 않는 다음 예제를 살펴보세요:
<?php
class ParentClass {
public static function create() {
return new self();
}
public static function getClassName() {
return self::class;
}
}
class ChildClass extends ParentClass {}
$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();
출력:
ParentClass
ParentClassChildClass::create()를 호출했지만 self::는 컴파일 시간에 확인되기 때문에 ParentClass 객체를 얻었습니다. 이제 static::을 대신 사용해 보겠습니다.
<?php
class ParentClass {
public static function create() {
return new static();
}
public static function getClassName() {
return static::class;
}
}
class ChildClass extends ParentClass {}
$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();
출력:
ChildClass
ChildClassstatic::을 사용하면 PHP는 런타임까지 기다렸다가 사용할 클래스를 결정합니다. 결정이 지연되기 때문에 이를 "지연" 바인딩이라고 합니다. 이는 factory 메서드와 상속을 존중해야 하는 모든 정적 메서드에 필수적입니다.
핵심 요점: 자식 클래스가 정적 동작을 올바르게 상속하고 사용자 지정하도록 하려면 self:: 대신 static::을 사용하세요.
챌린지
쉬움late static binding의 강력한 기능을 보여 주는 model registry 시스템을 만들어 보겠습니다. 자식 class가 상속할 수 있는 factory method를 포함한 기본 Model class를 만들고, static:: 덕분에 각 자식 class가 부모가 아니라 자기 자신에 대한 instance를 올바르게 생성하도록 합니다.
코드를 네 개의 파일로 구성합니다:
Model.php: 보호된 static property$tableName이"models"로 설정된 기본Modelclass를 Create합니다.new static()을 사용하여 이를 호출한 class의 새 instance를 Returns하는 static methodcreate()를 추가합니다.static::$tableName을 Returns하는 또 다른 static methodgetTable()도 추가합니다. 마지막으로static::class와static::$tableName을 사용하여"[ClassName] from table [tableName]"을 Returns하는describe()method를 추가합니다.User.php:Model을 extends하는Userclass를 Create합니다. 부모 파일을 포함합니다. static$tableNameproperty를"users"로 Override합니다. 이 class는 아무 changes 없이Model의 모든 methods를 inherited합니다.Product.php:Model을 extends하는Productclass를 Create합니다. 부모 파일을 포함합니다. static$tableNameproperty를"products"로 Override합니다. 마찬가지로 이 class는 부모의 모든 methods를 inherited합니다.main.php: User 및 Product 파일을 모두 포함합니다. inherited된create()factory method를 사용하여User와Product의 instance를 각각 Create합니다. 각 instance에 대해describe()를 Call하고 result를 한 줄에 하나씩 Print합니다. 그런 다음User::getTable()과Product::getTable()을 사용하여 각 class의 table 이름을 각각 한 줄에 하나씩 Print합니다.
여기서 중요한 점은 create() 및 getTable() methods가 부모 Model class에만 정의되어 있지만, static::이 binding을 runtime까지 지연하기 때문에 자식 class에서도 올바르게 작동한다는 것입니다. User::create()를 Call하면 PHP는 Model instance가 아니라 User instance를 생성합니다. static::은 실제로 호출된 class를 가리키기 때문입니다.
출력에는 네 줄이 표시되어야 합니다. User instance의 설명, Product instance의 설명, User table 이름, Product table 이름입니다.
직접 해보기
<?php
require_once 'User.php';
require_once 'Product.php';
// TODO: 상속된 create() 팩토리 메서드를 사용하여 User 인스턴스를 생성하세요
// TODO: 상속된 create() 팩토리 메서드를 사용하여 Product 인스턴스를 생성하세요
// TODO: User 인스턴스에서 describe()를 호출하고 결과를 출력하세요
// TODO: Product 인스턴스에서 describe()를 호출하고 결과를 출력하세요
// TODO: User::getTable()을 출력하세요
// TODO: Product::getTable()을 출력하세요
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 PHP 컴파일러