การลบล้างค่าคงที่คลาสเทียบกับคุณสมบัติ


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...
Luke Sawczak

2
มีกรณีการใช้งานที่ดีเพียงพอแน่นอนแม้จะมีการลบล้างอย่างต่อเนื่อง:]
Arziel

คำตอบ:


197

self::ไม่รับรู้การสืบทอดและอ้างถึงคลาสที่กำลังดำเนินการอยู่เสมอหากคุณใช้ php5.3 + คุณอาจลองstatic::TESTเหมือนที่static::รับรู้เกี่ยวกับการสืบทอด

ความแตกต่างคือstatic::ใช้ "late static binding" ค้นหาข้อมูลเพิ่มเติมที่นี่:

http://php.net/manual/th/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

น่ากลัว ขอขอบคุณสำหรับคำชี้แจงและสำหรับการให้ข้อมูลเพิ่มเติมเกี่ยวกับการเชื่อมโยงแบบคงที่ (ซึ่งฉันยังไม่ได้สรุป)
Tom Auger

3
เนื่องจากtest()ไม่ใช่วิธีคงที่ทำไมไม่ใช้$this::TESTกับ PHP5.3 +
Xenos

สวัสดี @Xenos - เป้าหมายของตัวอย่างคือการแสดงให้เห็นว่าโค้ดระดับอินสแตนซ์ที่เรียกใช้งานในคลาสที่หนึ่งกำลังดึงค่าคงที่จากคลาส 2 self :: TEST จะส่งคืน "test1" โดยที่ static :: TEST ส่งคืน "test2" ที่คาดหวัง - หวังว่าจะช่วยได้ขอบคุณสำหรับการตอบกลับ!
David Farrell

สวัสดี @DavidFarrell - ใช่ฉันมีself::/ static::ความแตกต่าง แต่ฉันไม่เข้าใจว่าทำไมต้องใช้static::แทน$this::(not self::) มีความแตกต่างระหว่าง$this::และstatic::(เนื่องจากมีระหว่างstatic::/ $this::และself::) หรือไม่?
Xenos

17

ใน PHP self หมายถึงคลาสที่มีการกำหนดวิธีการหรือคุณสมบัติที่เรียกว่า ดังนั้นในกรณีของคุณคุณกำลังโทรselfเข้าChildClassดังนั้นมันจึงใช้ตัวแปรจากคลาสนั้น จากนั้นคุณใช้selfในParentClassดังนั้นมันจะอ้างถึงตัวแปรในคลาสนั้น

หากคุณยังต้องการให้คลาสลูกแทนที่constคลาสแม่ให้ปรับโค้ดต่อไปนี้ในคลาสพาเรนต์ของคุณเป็น:

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

สังเกตstaticคำหลัก ซึ่งใช้ "การเชื่อมโยงแบบคงที่ล่าช้า" ตอนนี้คุณเป็นคลาสผู้ปกครองจะเรียก const ของคลาสลูกของคุณ


มือโปร. static :: made job ในนามธรรมแทนที่จะเป็นตัวเอง ::
Błażej Krzakala
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.