클래스 상수 대 속성 재정의


99

아래 시나리오에서 클래스 상수가 상속되는 방식과 인스턴스 변수가 다른 이유를 더 잘 이해하고 싶습니다.

<?php
class ParentClass {
    const TEST = "ONE";
    protected $test = "ONE";

    public function showTest(){
        echo self::TEST;
        echo $this->test;
    }
}

class ChildClass extends ParentClass {
    const TEST = "TWO";
    protected $test = "TWO";

    public function myTest(){
        echo self::TEST;
        echo $this->test;
    }
}

$child = new ChildClass();
$child->myTest();
$child->showTest();

산출:

TWO
TWO
ONE
TWO

위 코드에서 ChildClass에는 showTest () 메서드가 없으므로 상속에 의해 ParentClass showTest () 메서드가 사용됩니다. 결과는 메서드가 ParentClass에서 실행되기 때문에 TEST 상수의 ParentClass 버전이 평가되고있는 반면 상속을 통해 ChildClass 컨텍스트 내에서 평가되기 때문에 ChildClass 멤버 변수 $ test가 평가되고 있음을 보여줍니다.

설명서를 읽었지만이 뉘앙스에 대한 언급이 보이지 않는 것 같습니다. 누구든지 나를 위해 빛을 비출 수 있습니까?


WTF? 지속적인 재정의!? 이러지마! 못!
qwert_ukg

2
@qwert_ukg 맞습니다. 누군가는 그것을 PHP 개발자에게 전달해야합니다. 또는 적어도 수 final...
누가 복음 Sawczak에게

1
지속적인 재정의에도 충분한 사용 사례가 있습니다.]
Arziel

답변:


194

self::상속을 인식하지 않고 항상 실행되는 클래스를 참조합니다. php5.3 +를 사용하는 경우 상속 인식 static::TEST으로 시도 할 수 있습니다 static::.

차이점은 static::"지연 정적 바인딩" 을 사용 한다는 것 입니다. 여기에서 자세한 정보를 찾으십시오.

http://php.net/manual/en/language.oop5.late-static-bindings.php

내가 작성한 간단한 테스트 스크립트는 다음과 같습니다.

<?php

class One
{
    const TEST = "test1";

    function test() { echo static::TEST; }
}
class Two extends One
{
    const TEST = "test2";
}

$c = new Two();

$c->test();

산출

test2

22
+를 언급 static::합니다.
Jason McCreary 2012

대박. 설명을 해주셔서 감사하고 후기 정적 바인딩에 대한 추가 정보를 제공 해주셔서 감사합니다.
Tom Auger

3
때문에 test()왜 사용하지 않는 정적 메서드 아닌 $this::TESTPHP5.3 +로?
Xenos

안녕하세요 @Xenos-이 예제의 목표는 클래스 1에서 실행되는 인스턴스 수준 코드가 클래스 2에서 정적 값을 검색하고 있음을 보여주는 것이 었습니다. self :: TEST는 static :: TEST가 예상 한 "test2"를 반환하는 "test1"을 반환했을 것입니다.-도움이 되었기를 바랍니다. 회신 해 주셔서 감사합니다!
David Farrell

안녕하세요 @DavidFarrell-예, self::/ static::차이가 있지만 (아님 ) static::대신 사용 하는 이유를 모르겠습니다 . 와 사이에 차이가 있습니까 ( / 와 사이에 하나가 있기 때문에 )? $this::self::$this::static::static::$this::self::
Xenos 2014-06-29

17

PHP에서 self는 호출 된 메서드 또는 속성이 정의 된 클래스를 나타냅니다. 그래서 경우에 당신이 전화하는거야 self에서 ChildClass이 클래스에서 변수를 사용하므로. 그런 다음 selfin 을 사용 ParentClass하므로 해당 클래스의 변수를 참조합니다.

그래도 자식 클래스가 부모 클래스를 재정의하도록 const하려면 부모 클래스의 다음 코드를 이에 맞게 조정합니다.

public function showTest(){
    echo static::TEST;
    echo $this->test;
}

static키워드에 유의하십시오 . 이것은 "지연 정적 바인딩"을 사용합니다. 이제 부모 클래스가 자식 클래스의 const를 호출합니다.


찬성. 정적 :: 대신 :: 자기의 추상화에서 작업 만든
투입 Blažej Krzakala
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.