늦은 정적 바인딩의 기본 개념
늦은 정적 바인딩(Late Static Binding)의 핵심 아이디어는 상속의 개념과 'self' 키워드가 동일한 규칙을 따르지 않는다는 점입니다. 예를 들어, 부모 클래스에 정의된 메서드 'fun'이 자식 클래스에서 호출되더라도 'self'는 예상과 달리 자식 클래스를 가리키지 않습니다.
늦은 정적 바인딩은 이러한 문제를 해결하기 위해 새로운 키워드인 static을 도입했습니다. static을 사용하면 해당 함수가 런타임에 실제로 호출된 클래스, 즉 함수가 처음 사용된 클래스에 바인딩됩니다. 또한 정적(static) 함수나 변수는 일반적으로 컴파일 시점이 아닌 런타임에 실행됩니다. 따라서 정적 변수에 값을 동적으로 할당해야 할 때 그 작업이 런타임에 수행되며, 이것이 바로 '늦은(late) 정적 바인딩'이라고 불리는 이유입니다.
참고로 늦은 정적 바인딩은 PHP 5.3.0부터 도입된 기능으로, 상속 구조에서 부모 클래스의 메서드가 실제 호출된 클래스를 기준으로 동작해야 할 때 특히 유용합니다.
예제 코드
<?php
class student
{
public static $my_name = 'Joe';
public static function getName()
{
return "The name of the student is : " . self::$my_name;
}
public static function getAge()
{
echo static::getName();
}
}
class Professor extends student
{
public static function getName()
{
return "The name of the student is : " . self::$my_name . " and age is 24.";
}
}
student::getAge();
echo "\n";
Professor::getAge();
?>
실행 결과
The name of the student is : Joe The name of the student is : Joe and age is 24.
코드 설명
'student'라는 클래스에는 학생의 이름을 저장하는 정적 변수와 그 이름을 반환하는 getName() 함수가 있습니다. 또 다른 함수인 getAge()는 학생의 나이 정보를 출력하는 역할을 하며, 내부에서 static::getName()을 호출합니다.
'Professor' 클래스는 student 클래스를 상속받으며, getName() 함수를 오버라이드(재정의)하여 나이 정보까지 추가로 반환합니다. 마지막으로 getAge() 함수를 student 클래스와 Professor 클래스 양쪽에서 각각 호출하면, static 키워드 덕분에 호출 시점에 실제 사용된 클래스의 getName()이 실행되어 위와 같은 결과가 출력됩니다.
만약 여기서 static 대신 self를 사용했다면, Professor::getAge()를 호출했을 때도 부모 클래스의 getName()이 실행되어 두 번째 줄의 "...and age is 24." 문구가 출력되지 않았을 것입니다. 이것이 self와 static의 결정적인 차이이며, 늦은 정적 바인딩이 필요한 이유입니다.