เหตุใด php จึงอนุญาตให้เปลี่ยน const ในคลาสย่อย

ฉันไม่เข้าใจว่าทำไมรหัสต่อไปนี้จึงใช้งานได้ STEALTH ไม่ได้ถูกกำหนดใหม่ในคลาสย่อย... แม้ว่าจะถูกประกาศเป็น const ในพาเรนต์ใช่หรือไม่ โปรดทราบว่าฉันรู้สึกว่า const ป้องกันไม่ให้มีการกำหนดตัวแปรใหม่!

  class Person {
    const STEALTH = "MINIMUM";
  }

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

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

โปรดทราบว่าฉันไม่ได้ถามเกี่ยวกับตัวดำเนินการแก้ไขขอบเขต ฉันคิดว่าฉันเข้าใจความแตกต่างระหว่างการพิมพ์ Ninja::STEALTH กับ Person::STEALTH ฉันแค่แปลกใจที่นินจาสามารถสืบทอดตัวแปร const ได้แต่ยังมีความสามารถในการกำหนดมันใหม่ได้!


person Grateful    schedule 11.07.2017    source แหล่งที่มา
comment
การแทนที่ค่าคงที่ของคลาสเทียบกับคุณสมบัติที่เป็นไปได้   -  person mingos    schedule 11.07.2017
comment
ใครบอกว่ามันถูกนิยามใหม่?   -  person u_mulder    schedule 11.07.2017
comment
Person::STEALTH และ Ninja::STEALTH เป็นสองสิ่งที่แตกต่างกันอย่างชัดเจน...   -  person deceze♦    schedule 11.07.2017
comment
@deceze ใช่ฉันเห็นแล้ว ฉันไม่ได้ถามเกี่ยวกับตัวดำเนินการแก้ไขขอบเขต ฉันรู้สึกประหลาดใจที่นินจาได้รับมรดกจากบุคคลแต่ยังสามารถให้คำนิยามใหม่กับ STEALTH ได้   -  person Grateful    schedule 11.07.2017
comment
ไม่มีการไม่ให้คำจำกัดความใหม่ที่นี่ คุณมีค่าคงที่ที่แตกต่างกัน สอง   -  person u_mulder    schedule 11.07.2017
comment
@u_mulder แต่ถ้าฉันไม่มีคำจำกัดความใหม่อย่างต่อเนื่องที่สองนั้น ... และ echo Ninja::STEALTH ฉันจะสามารถพิมพ์ค่าของผู้ปกครอง MINIMUM ได้หรือไม่ ดูเหมือนว่าค่าจะถูกสืบทอดมา.. และหากเป็นเช่นนั้น ทำไมฉันจึงสามารถกำหนดค่าคงที่ NEW ด้วยชื่อเดียวกันของค่าคงที่ที่มีอยู่แล้วผ่านการสืบทอดได้ โดยปกติ ฉันเข้าใจการแทนที่... แต่ในกรณีนี้ ฉันจะแทนที่ตัวแปร const ได้อย่างไร   -  person Grateful    schedule 12.07.2017
comment
หยุดคิดใน values คิดใน items คุณมี item ประเภท constant ในคลาส Person เนื่องจากคลาส Ninja สืบทอดคลาส Person คลาส Ninja จึงรู้ทุกๆ item (ซึ่งไม่ใช่ไพรเวต) ของคลาสพาเรนต์ ดังนั้น คลาส Ninja รู้เกี่ยวกับ item ประเภท constant ตอนนี้ คุณกำหนด item ประเภท constant ใหม่ด้วยชื่อเดียวกันในคลาส Ninja ดังนั้นคุณมี สอง รายการ: หนึ่งรายการ item จากคลาสหลัก และรายการที่สอง item ใน Ninja เอง   -  person u_mulder    schedule 12.07.2017


คำตอบ (2)


const เพียงหมายความว่าไม่สามารถ แก้ไขค่าขณะรันไทม์ ได้ มันไม่ได้จำกัดคลาสไม่ให้กำหนดค่าคงที่ด้วยชื่อเดียวกันอย่างอิสระ สิ่งเดียวก็คือกฎการสืบทอดจะกำหนดเวลาและวิธีที่มูลค่าของผู้ปกครองอาจถูกบดบังโดยมูลค่าของเด็ก

person deceze♦    schedule 11.07.2017

ฉันรู้สึกว่า const ป้องกันไม่ให้มีการกำหนดตัวแปรใหม่!

const ป้องกันไม่ให้มีการแก้ไขค่า

ไม่สามารถกำหนดวัตถุสองชิ้นที่มีชื่อเดียวกันได้โดยใช้ define() . นอกจากนี้ ยังไม่สามารถกำหนดวัตถุสองวัตถุที่แตกต่างกันซึ่งมีชื่อเดียวกันโดยใช้ const ได้ สมาชิกคลาส const สามารถเข้าถึงได้โดยใช้ชื่อเต็มเสมอ (ชื่อคลาส + :: + ชื่อคงที่)

ชื่อของค่าคงที่ STEALTH ที่กำหนดโดยคลาส Person คือ Person::STEALTH คลาส Ninja ประกาศค่าคงที่ Ninja::STEALTH

พวกมันเป็นวัตถุที่แตกต่างกัน

คุณสมบัติของคลาส const (และ static) จะไม่สืบทอดในลักษณะเดียวกับคุณสมบัติของอินสแตนซ์ หากคุณสมบัติ const ที่กำหนดโดยคลาสฐานไม่ได้ถูกปิดบังโดยอ็อบเจ็กต์อื่นที่มีชื่อเดียวกันซึ่งกำหนดโดยคลาสลูก คุณสมบัติคลาสฐาน const จะถูกคัดลอกในคลาสลูกและสามารถเข้าถึงได้โดยใช้ชื่อคลาสลูก

ตัวอย่างเช่น:

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'

เนื่องจากคลาส Citizen ขยายคลาส Person และไม่ได้กำหนดค่าคงที่ STEALTH ของตัวเอง Citizen::STEALTH จึงเป็นสำเนาของ Person::STEALTH1

ค่าคงที่ของคลาสคืออ็อบเจ็กต์โกลบอลที่มีชื่อสวยงาม (และตัวปรับแต่งการมองเห็นคลาสตั้งแต่ PHP 7.0)

person axiac    schedule 11.07.2017
comment
โอเค... มันสมเหตุสมผลสำหรับฉันแล้วตอนนี้! ขอบคุณ! - person Grateful; 11.07.2017
comment
ดูเหมือนว่าตัวแปร const ได้รับการสืบทอดมา ฉันแสดงความคิดเห็น const STEALTH = "MAXIMUM"; ในชั้นเรียนนินจา.. และยังสามารถพิมพ์ออกมาได้ Ninja::STEALTH มันพิมพ์ค่าที่สืบทอดมา MINIMUM.... ฉันสับสนอีกแล้ว! - person Grateful; 12.07.2017
comment
แท้จริงแล้ว คุณสมบัติคลาส const และ static ของคลาสฐานสามารถเข้าถึงได้จากคลาสย่อยโดยใช้ชื่อของคลาสย่อย จากมุมมองนี้ พวกเขาจะได้รับมรดก สิ่งที่ฉันหมายถึงคือ Ninja::STEALTH เป็นวัตถุเดียวกันกับ Person::STEALTH และไม่ใช่สำเนา นี่เป็นปัญหาในคุณสมบัติ static (ไม่เป็นปัญหาใน const เนื่องจากไม่สามารถเปลี่ยนแปลงได้) ฉันเดาว่าฉันจะจัดรูปแบบคำตอบใหม่ - person axiac; 12.07.2017