PHP에서 늦은 정적 바인딩은 정확히 무엇입니까?
답변
PHP 매뉴얼에서 Late Static Bindings 를 반드시 읽으십시오 . 그러나 간단한 요약을 해 드리겠습니다.
기본적으로 self
키워드가 동일한 상속 규칙을 따르지 않는다는 사실로 요약됩니다 . self
항상 사용되는 클래스로 확인됩니다. 즉, 부모 클래스에서 메서드를 만들어 자식 클래스에서 호출하면 self
예상대로 자식을 참조하지 않습니다.
늦은 정적 바인딩은 static
키워드 의 새로운 용도를 소개 하며이 단점을 해결합니다. 를 사용할 때 static
처음 사용하는 클래스를 나타냅니다. 런타임 클래스에 ‘바인딩’됩니다.
이것이 두 가지 기본 개념입니다. 방법은 self
, parent
과 static
가 작동 static
더 세부 사항에 미묘한, 그래서보다는 이동 될 수 놀이에, 나는 강하게 당신이 매뉴얼 페이지 예제를 공부하는 것이 좋습니다 것입니다. 각 키워드의 기본 사항을 이해하면 어떤 결과를 얻을 수 있는지보기 위해 예제가 필요합니다.
답변
에서 PHP : 늦은 정적 바인딩 – 수동 :
PHP 5.3.0부터 PHP는 정적 상속이라는 맥락에서 호출 된 클래스를 참조하는 데 사용할 수있는 후기 정적 바인딩이라는 기능을 구현합니다.
늦은 정적 바인딩은 런타임에 처음 호출 된 클래스를 참조하는 키워드를 도입하여 이러한 제한을 해결하려고합니다. … 새로운 키워드를 도입하지 않고
static
이미 예약 된 키워드를 사용하기로 결정했습니다 .
예를 보자.
<?php
class Car
{
public static function run()
{
return static::getName();
}
private static function getName()
{
return 'Car';
}
}
class Toyota extends Car
{
public static function getName()
{
return 'Toyota';
}
}
echo Car::run(); // Output: Car
echo Toyota::run(); // Output: Toyota
?>
늦은 정적 바인딩은 마지막 “비 전달 호출”에 명명 된 클래스를 저장하여 작동합니다. 정적 메소드 호출의 경우이 클래스는 명시 적으로 이름이 지정된 클래스입니다 (일반적으로
::
연산자 왼쪽에있는 클래스 ). 비 정적 메서드 호출의 경우 객체의 클래스입니다. A “전달 호출”에 의해 도입 정적이다self::
,parent::
,static::
, 또는 클래스 계층 구조에가는 경우,forward_static_call()
. 이 함수get_called_class()
는 호출 된 클래스 이름으로 문자열을 검색하고static::
해당 범위를 소개 하는 데 사용할 수 있습니다 .
답변
명백한 행동은 없습니다 :
다음 코드는 ‘alphabeta’를 생성합니다.
class alpha {
function classname(){
return __CLASS__;
}
function selfname(){
return self::classname();
}
function staticname(){
return static::classname();
}
}
class beta extends alpha {
function classname(){
return __CLASS__;
}
}
$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta
그러나 베타 클래스에서 classname 함수 선언을 제거하면 결과로 ‘alphaalpha’가 표시됩니다.
답변
“PHP Master write 첨단 코드”라는 책에서 인용하고 있습니다.
늦은 정적 바인딩은 PHP 5.3에서 소개 된 기능입니다. 이를 통해 부모 클래스에서 정적 메서드를 상속하고 호출되는 자식 클래스를 참조 할 수 있습니다.
이것은 정적 메소드를 가진 추상 클래스를 가질 수 있고 self :: method () 대신 static :: method () 표기법 을 사용하여 하위 클래스의 구체적인 구현을 참조 할 수 있음을 의미합니다
.
공식 PHP 문서도 참조하십시오 :
http://php.net/manual/en/language.oop5.late-static-bindings.php
늦은 정적 바인딩을 설명하는 가장 명확한 방법은 간단한 예입니다. 아래의 두 클래스 정의를 살펴보고 계속 읽으십시오.
class Vehicle {
public static function invokeDriveByStatic() {
return static::drive(); // Late Static Binding
}
public static function invokeStopBySelf() {
return self::stop(); // NOT Late Static Binding
}
private static function drive(){
return "I'm driving a VEHICLE";
}
private static function stop(){
return "I'm stopping a VEHICLE";
}
}
class Car extends Vehicle {
protected static function drive(){
return "I'm driving a CAR";
}
private static function stop(){
return "I'm stopping a CAR";
}
}
우리는 부모 클래스 (차량)와 자식 클래스 (차)를 봅니다. 학부모 클래스에는 두 가지 공개 메소드가 있습니다.
invokeDriveByStatic
invokeStopBySelf
부모 클래스에는 2 개의 개인 메소드가 있습니다 :
drive
stop
자식 클래스는 다음 두 가지 메소드를 대체합니다.
drive
stop
이제 public 메소드를 호출 해 봅시다 :
invokeDriveByStatic
invokeStopBySelf
자신에게 물어 : 어떤 클래스를 발동를 invokeDriveByStatic
/ invokeStopBySelf
? 부모 또는 자식 수업?
아래를 살펴보십시오.
// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a VEHICLE
echo Vehicle::invokeStopBySelf(); // I'm stopping a VEHICLE
// !!! This is Late Static Binding !!!!
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR
// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a VEHICLE
static
키워드는 단일 디자인 패턴으로 사용됩니다. 링크 참조 : https://refactoring.guru/design-patterns/singleton/php/example
답변
차이점을 보여주는 가장 간단한 예입니다.
참고, 자기 : $ C를
class A
{
static $c = 7;
public static function getVal()
{
return self::$c;
}
}
class B extends A
{
static $c = 8;
}
B::getVal(); // 7
늦은 정적 바인딩, 정적 :: $ c 참고
class A
{
static $c = 7;
public static function getVal()
{
return static::$c;
}
}
class B extends A
{
static $c = 8;
}
B::getVal(); // 8
답변
예를 들면 다음과 같습니다.
abstract class Builder {
public static function build() {
return new static;
}
}
class Member extends Builder {
public function who_am_i() {
echo 'Member';
}
}
Member::build()->who_am_i();
답변
“왜 이것을 사용해야합니까?” 관점에서 볼 때, 기본적으로 정적 메소드가 해석 / 실행되는 컨텍스트를 변경하는 방법입니다.
로 self
컨텍스트는 메소드를 원래 정의한 컨텍스트입니다. 를 사용하면 static
전화를 거는 사람입니다.