Mengganti konstanta kelas vs properti

99

Saya ingin lebih memahami mengapa, dalam skenario di bawah ini, ada perbedaan dalam cara konstanta kelas diwarisi vs. variabel instan.

<?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();

Keluaran:

TWO
TWO
ONE
TWO

Dalam kode di atas, ChildClass tidak memiliki metode showTest (), jadi metode ParentClass showTest () digunakan oleh pewarisan. Hasilnya menunjukkan bahwa karena metode ini dijalankan pada ParentClass, versi ParentClass dari konstanta TEST sedang dievaluasi, sedangkan karena metode tersebut mengevaluasi dalam konteks ChildClass melalui pewarisan, variabel anggota ChildClass $ test sedang dievaluasi.

Saya telah membaca dokumentasinya, tetapi tidak melihat ada penyebutan nuansa ini. Adakah yang bisa memberi penjelasan untuk saya?

Tom Auger
sumber
WTF? Penimpaan terus menerus !? Jangan lakukan ini! tidak pernah!
qwert_ukg
2
@qwertukg Memang. Seseorang harus mengkomunikasikannya kepada pengembang PHP. Atau setidaknya izinkan final...
Luke Sawczak
1
Ada beberapa kasus penggunaan yang cukup baik bahkan untuk
penggantian

Jawaban:

194

self::Tidak sadar-warisan dan selalu mengacu pada kelas yang dijalankannya. Jika Anda menggunakan php5.3 +, Anda dapat mencoba static::TESTseperti static::yang sadar-warisan.

Perbedaannya adalah yang static::menggunakan "pengikatan statis terlambat". Temukan informasi lebih lanjut di sini:

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

Berikut skrip pengujian sederhana yang saya tulis:

<?php

class One
{
    const TEST = "test1";

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

$c = new Two();

$c->test();

keluaran

test2
David Farrell
sumber
22
+ untuk disebutkan static::.
Jason McCreary
Hebat. Terima kasih atas klarifikasi dan untuk memberikan informasi tambahan tentang pengikatan statis-terlambat (yang belum saya cerna).
Tom Auger
3
Karena test()ini bukan metode statis, mengapa tidak menggunakan $this::TESTdengan PHP5.3 +?
Xenos
Hai @Xenos - Tujuan dari contoh ini adalah untuk menunjukkan bahwa kode tingkat instance yang dijalankan di kelas Satu mengambil nilai statis dari kelas Dua. self :: TEST akan mengembalikan "test1" di mana static :: TEST mengembalikan "test2" yang diharapkan - Semoga membantu, terima kasih telah membalas!
David Farrell
Hai @DavidFarrell - Ya, saya mengerti self::/ static::perbedaan tetapi saya tidak mengerti mengapa menggunakan static::alih-alih $this::(tidak self::). Apakah ada perbedaan antara $this::dan static::(karena ada satu antara static::/ $this::dan self::)?
Xenos
17

Dalam PHP, self mengacu pada kelas di mana metode atau properti yang disebut didefinisikan. Jadi dalam kasus Anda Anda menelepon selfdi ChildClass, sehingga menggunakan variabel dari kelas itu. Kemudian Anda gunakan selfin ParentClass, sehingga akan merujuk ke variabel di kelas itu.

jika Anda masih ingin kelas anak untuk mengganti constkelas induk, maka sesuaikan kode berikut di kelas induk Anda untuk ini:

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

Perhatikan statickata kuncinya. Ini menggunakan "pengikatan statis terlambat". Sekarang kelas orang tua Anda akan memanggil const dari kelas anak Anda.

w00
sumber
pro. statis :: pekerjaan dibuat dalam abstraksi alih-alih diri ::
Bła Krej Krzakala