Mengapa php mengizinkan const diubah di subkelas?

Saya tidak mengerti mengapa kode berikut berfungsi. Bukankah STEALTH sedang didefinisikan ulang di subkelas... meskipun dideklarasikan sebagai const di induknya? FYI, saya mendapat kesan bahwa const mencegah variabel didefinisikan ulang!

  class Person {
    const STEALTH = "MINIMUM";
  }

  class Ninja extends Person {          
    const STEALTH = "MAXIMUM";
  }

  echo Ninja::STEALTH; // prints out 'MAXIMUM'

Harap dicatat bahwa saya tidak bertanya tentang operator resolusi cakupan. Saya rasa saya memahami perbedaan antara mencetak Ninja::STEALTH vs Person::STEALTH. Saya hanya terkejut dengan kenyataan bahwa ninja dapat mewarisi variabel const namun memiliki kemampuan untuk mendefinisikannya kembali!


person Grateful    schedule 11.07.2017    source sumber
comment
Kemungkinan duplikat dari Mengganti konstanta kelas vs properti   -  person mingos    schedule 11.07.2017
comment
Siapa bilang itu didefinisikan ulang?   -  person u_mulder    schedule 11.07.2017
comment
Person::STEALTH dan Ninja::STEALTH jelas merupakan dua hal yang berbeda…   -  person deceze♦    schedule 11.07.2017
comment
@deceze Ya, saya bisa melihatnya. Saya tidak bertanya tentang operator resolusi cakupan. Saya terkejut dengan kenyataan bahwa ninja adalah orang yang mewarisi namun mampu mendefinisikan ulang STEALTH.   -  person Grateful    schedule 11.07.2017
comment
Tidak ada definisi ulang di sini. Anda memiliki dua konstanta yang berbeda.   -  person u_mulder    schedule 11.07.2017
comment
@u_mulder Tapi jika saya tidak memiliki redefinisi konstan kedua... dan echo Ninja::STEALTH, saya akan dapat mencetak nilai induk MINIMUM? Sepertinya nilainya sedang diwarisi.. dan jika demikian, mengapa saya dapat mendefinisikan konstanta BARU dengan nama SAMA dari sebuah konstanta yang sudah ada melalui pewarisan? Biasanya, saya memahami penggantian... tetapi dalam kasus ini, bagaimana saya bisa mengganti variabel const?   -  person Grateful    schedule 12.07.2017
comment
Berhentilah berpikir di values, pikirkan di items. Anda memiliki item tipe constant di kelas Person. Karena kelas Ninja mewarisi kelas Person, kelas Ninja mengetahui setiap item (yang bukan privat) dari kelas induk. Jadi, kelas Ninja mengetahui tentang item bertipe constant. Sekarang, Anda mendefinisikan item baru bertipe constant dengan nama yang sama di kelas Ninja. Jadi, Anda memiliki dua item: satu item dari kelas induk dan yang kedua item di Ninja itu sendiri.   -  person u_mulder    schedule 12.07.2017


Jawaban (2)


const hanya berarti bahwa nilainya tidak dapat diubah pada waktu proses. Itu tidak membatasi kelas untuk secara mandiri mendefinisikan sebuah konstanta dengan nama yang sama; satu-satunya hal adalah aturan pewarisan akan menentukan kapan dan bagaimana nilai orang tua dapat dibayangi oleh nilai anak.

person deceze♦    schedule 11.07.2017

Saya mendapat kesan bahwa const mencegah variabel didefinisikan ulang!

const mencegah nilai diubah.

Tidak mungkin mendefinisikan dua objek berbeda yang memiliki nama yang sama menggunakan define() . Juga tidak mungkin untuk mendefinisikan dua objek berbeda yang memiliki nama yang sama menggunakan const. Anggota kelas const selalu diakses menggunakan nama lengkapnya (nama kelas + :: + nama konstan).

Nama konstanta STEALTH yang didefinisikan oleh kelas Person adalah Person::STEALTH. Kelas Ninja mendeklarasikan konstanta Ninja::STEALTH.

Mereka adalah objek yang berbeda.

Properti kelas const (dan static) tidak diwarisi dengan cara yang sama seperti properti instance. Jika properti const yang ditentukan oleh kelas dasar tidak ditutupi oleh objek lain dengan nama yang sama yang ditentukan oleh kelas anak, properti kelas dasar const disalin di kelas anak dan dapat diakses menggunakan nama kelas anak.

Misalnya:

class Person {
    const STEALTH = "MINIMUM";
}

class Citizen extends Person {

}

class Ninja extends Person {          
    const STEALTH = "MAXIMUM";
}

echo Person::STEALTH;    // prints out 'MINIMUM'
echo Citizen::STEALTH;   // prints out 'MINIMUM'; same as Person::STEALTH 
echo Ninja::STEALTH;     // prints out 'MAXIMUM'

Karena kelas Citizen merupakan perluasan kelas Person dan tidak mendefinisikan konstanta STEALTH miliknya sendiri, Citizen::STEALTH adalah salinan dari Person::STEALTH1.

Konstanta kelas adalah objek global dengan nama mewah (dan pengubah visibilitas kelas sejak PHP 7.0).

person axiac    schedule 11.07.2017
comment
Oke... itu lebih masuk akal bagiku sekarang! Terima kasih! - person Grateful; 11.07.2017
comment
Tampaknya const variabel DIwariskan. Saya berkomentar const STEALTH = "MAXIMUM"; di kelas Ninja.. dan masih bisa mencetak Ninja::STEALTH. Itu mencetak nilai warisan MINIMUM.... Saya bingung lagi! - person Grateful; 12.07.2017
comment
Memang benar, properti kelas const dan static dari kelas dasar dapat diakses dari kelas anak menggunakan nama kelas anak. Dari sudut pandang ini, mereka diwariskan. Yang saya maksud adalah Ninja::STEALTH adalah objek yang sama dengan Person::STEALTH dan bukan salinan. Ini menyusahkan pada properti static (tidak terlalu merepotkan pada const karena tidak dapat diubah). Saya kira saya akan merumuskan kembali jawabannya. - person axiac; 12.07.2017