นอกเหนือจากการจำกัดการเข้าถึงแล้ว วิธีการเข้าถึงยังกำหนดวิธีการที่จะเรียกโดยคลาสย่อยหรือคุณสมบัติที่จะเข้าถึงโดยคลาสย่อย ความสัมพันธ์ระหว่างการเรียกฟังก์ชันและฟังก์ชันเอง และความสัมพันธ์ระหว่างการเข้าถึงของสมาชิกและที่อยู่หน่วยความจำตัวแปร เรียกว่าการผูกมัด
การผูกในภาษาคอมพิวเตอร์มีสองประเภทหลัก - การผูกแบบคงที่และการผูกแบบไดนามิก การเชื่อมโยงแบบคงที่เกิดขึ้นระหว่างโครงสร้างข้อมูลและโครงสร้างข้อมูลก่อนที่โปรแกรมจะถูกดำเนินการ การเชื่อมโยงแบบคงที่เกิดขึ้นในเวลารวบรวมและดังนั้นจึงไม่สามารถใช้ข้อมูลรันไทม์ใด ๆ โดยกำหนดเป้าหมายการเรียกใช้ฟังก์ชันและเนื้อความของฟังก์ชัน หรือตัวแปรและบล็อกของหน่วยความจำ เนื่องจาก PHP เป็นภาษาแบบไดนามิก จึงไม่ได้ใช้การเชื่อมโยงแบบคงที่ แต่สามารถจำลองการเชื่อมโยงแบบคงที่ได้
การเชื่อมโยงแบบไดนามิกจะใช้เฉพาะข้อมูลที่มีอยู่ในรันไทม์สำหรับคำขอการเข้าถึงที่สร้างขึ้นระหว่างรันไทม์ ในโค้ดเชิงวัตถุ การผูกแบบไดนามิกหมายถึงการตัดสินใจว่าจะเรียกใช้เมธอดใดหรือเข้าถึงคุณสมบัติใดจะขึ้นอยู่กับคลาสนั้นเอง ไม่ใช่ในขอบเขตการเข้าถึง
การดำเนินการของสมาชิกสาธารณะและสมาชิกที่ได้รับการคุ้มครองจะคล้ายกับการทำงานของฟังก์ชันใน PHP เวอร์ชันก่อนหน้า โดยใช้การเชื่อมโยงแบบไดนามิก ซึ่งหมายความว่าหากวิธีการเข้าถึงสมาชิกของคลาสที่ถูกแทนที่ในคลาสย่อยและเป็นอินสแตนซ์ของคลาสย่อย สมาชิกคลาสย่อยจะถูกเข้าถึง (แทนที่จะเข้าถึงสมาชิกในคลาสพาเรนต์)
ดูตัวอย่างที่ 6.10 โค้ดนี้แสดงผลว่า "เฮ้! ฉันคือลูกชาย" เพราะเมื่อ PHP เรียก getSalutation จะเป็นอินสแตนซ์ของ Son ซึ่งจะเขียนทับคำทักทายในภาษา Father หากคำทักทายเป็นแบบสาธารณะ PHP จะสร้างผลลัพธ์เดียวกัน การดำเนินการของวิธีการแทนที่นั้นคล้ายกันมาก ใน Son การเรียกเพื่อระบุตัวตนจะเชื่อมโยงกับวิธีการนั้น
แม้ว่าวิธีการเข้าถึงจะลดลงจากการป้องกันสู่สาธารณะในคลาสย่อย แต่การเชื่อมโยงแบบไดนามิกจะยังคงเกิดขึ้น ตามหลักการของการใช้วิธีการเข้าถึง มันเป็นไปไม่ได้ที่จะปรับปรุงข้อจำกัดการเข้าถึงสำหรับสมาชิกของคลาส ดังนั้นการเปลี่ยนวิธีการเข้าถึงจากสาธารณะเป็น ที่ได้รับการคุ้มครองไม่สามารถดำเนินการต่อไปได้
รายการ 6.10 การผูกแบบไดนามิก
คลาสการผูกแบบไดนามิก พ่อ
-
protected $salutation = "สวัสดี!"; //สวัสดี ฟัง
ก์ชั่นสาธารณะ getSalutation()
-
print("$this->คำทักทาย");
$นี่->ระบุ();
}
ระบุฟังก์ชันที่ได้รับการป้องกัน ()
-
print("ฉันคือพ่อ.
เอ็น");
-
};
คลาส ลูกชาย ขยายพ่อ
-
protected $salutation = "เฮ้!"; //protected $salutation ในคลาสพาเรนต์ถูกเขียนทับ
ฟังก์ชันป้องกัน ระบุ() //protected ระบุ() ในคลาสพาเรนต์ถูกเขียนทับ
-
print("ฉันคือลูกชาย.
เอ็น");
-
};
$obj = ลูกชายคนใหม่();
$obj->getSalutation(); //เอาท์พุต เฮ้!
?>
//หมายเหตุ: getSalutation() ไม่ได้ถูกแทนที่ในคลาสย่อย แต่จริงๆ แล้วยังมี getSalutation() $salutation และระบุ() ในคลาสนี้
//เชื่อมโยงแบบไดนามิกกับเมธอด getSalutation() ในอินสแตนซ์ของคลาสย่อย Son ดังนั้นเมธอด getSalutation() ของอินสแตนซ์ Son จึงถูกเรียก
//คำทักทายสมาชิกและ ident() ในคลาส Son จะถูกเรียกแทนคำทักทายสมาชิก และ ident() ในคลาสพาเรนต์
สมาชิกส่วนตัวมีอยู่เฉพาะในคลาสที่พวกเขาอยู่ ต่างจากสมาชิกสาธารณะและสมาชิกที่ได้รับการคุ้มครอง จำลองการผูกแบบคงที่ ดูตัวอย่าง 6.11 มันพิมพ์ว่า "สวัสดี ฉันคือพ่อ" แม้ว่าคลาสย่อยจะเขียนทับค่าของคำทักทาย แต่สคริปต์จะผูกคำทักทายนี้กับคลาสปัจจุบัน Father
รายการ 6.11 สมาชิกที่มีผลผูกพันและส่วนตัว
ชั้นพ่อ
-
$salutation ส่วนตัว = "สวัสดี!"
;
-
print("$this->คำทักทาย");
$นี่->ระบุ();
}
ระบุฟังก์ชันส่วนตัว()
-
print("ฉันคือพ่อ.
เอ็น");
-
}
คลาส ลูกชายขยายพ่อ
-
$salutation ส่วนตัว = "เฮ้!";
ฟังก์ชั่นส่วนตัวระบุ ()
-
print("ฉันคือลูกชาย.
เอ็น");
-
}
$obj = ลูกชายคนใหม่();
$obj->getSalutation(); //Output สวัสดี!
?>
ข้อดีของการเชื่อมโยงแบบไดนามิกคืออนุญาตให้คลาสที่สืบทอดมาเปลี่ยนพฤติกรรมของคลาสพาเรนต์ในขณะที่ยังคงรักษาอินเทอร์เฟซและฟังก์ชันของคลาสพาเรนต์ไว้ได้ เนื่องจากการใช้การเชื่อมโยงแบบไดนามิก เวอร์ชันของ isAuthorized จึงถูกเรียกเข้ามา DeleteUser สามารถกำหนดได้ตามประเภทของวัตถุ หากเป็นผู้ใช้ทั่วไป การเรียก PHP User::isAuthorized จะส่งกลับ FALSE หากเป็นอินสแตนซ์ของ AuthorizedUser การเรียก PHP AuthorizedUser::isAuthorized จะทำให้ DeleteUser ดำเนินการได้อย่างราบรื่น
//haohappy หมายเหตุ: เพื่อให้ชัดเจนในประโยคเดียว มันคือประเภทวัตถุและวิธีการ การเชื่อมโยงแอตทริบิวต์ เมื่อเรียกวิธีการที่มีอยู่ในทั้งคลาสหลักและคลาสย่อยหรือการเข้าถึงแอตทริบิวต์ มันจะกำหนดประเภทของวัตถุก่อน อินสแตนซ์เป็นของแล้วเรียกวิธีการและคุณสมบัติในคลาสที่เกี่ยวข้อง
6.12 รายการประโยชน์ของ
คลาสการเชื่อมโยงแบบไดนามิกผู้ใช้ // ผู้ใช้
-
ฟังก์ชั่นที่ได้รับการป้องกัน isAuthorized() // ไม่ว่าจะเป็นผู้ใช้ที่ได้รับการรับรองความถูกต้องหรือไม่
-
กลับ(เท็จ);
}
ฟังก์ชั่นสาธารณะ getName() //รับชื่อ
-
กลับ($นี่->ชื่อ);
}
ฟังก์ชั่นสาธารณะ DeleteUser($username) //ลบผู้ใช้
-
ถ้า(!$this->ได้รับอนุญาต())
-
print("คุณไม่ได้รับอนุญาต.
เอ็น");
กลับ(เท็จ);
}
// ลบผู้ใช้
พิมพ์("ผู้ใช้ถูกลบ.
เอ็น");
-
}
คลาส AuthorizedUser ขยายผู้ใช้ // ผู้ใช้การรับรองความถูกต้อง
-
ฟังก์ชั่นที่ได้รับการป้องกัน isAuthorized() // เขียนทับ isAuthorized()
-
กลับ(จริง);
-
}
$user = ผู้ใช้ใหม่;
$admin = new AuthorizedUser;
//ไม่ได้รับอนุญาต
$user->deleteUser("Zeev");
//ได้รับอนุญาต
$admin->deleteUser("Zeev");
?>
เหตุใดสมาชิกคลาสส่วนตัวจึงจำลองการผูกแบบคงที่ เพื่อตอบคำถามนี้ คุณต้องจำไว้ว่าเหตุใดคุณจึงต้องมีสมาชิกส่วนตัว เมื่อใดจึงสมเหตุสมผลที่จะใช้พวกเขาแทนสมาชิก
ส่วนตัวเท่านั้น หากคุณไม่ต้องการ คลาสย่อยที่จะสืบทอด ใช้เฉพาะเมื่อเปลี่ยนแปลงหรือเชี่ยวชาญพฤติกรรมของคลาสพาเรนต์ นี่เป็นเรื่องธรรมดาน้อยกว่าที่คุณคิด โดยทั่วไป ลำดับชั้นของอ็อบเจ็กต์ที่ดีควรอนุญาตให้ฟังก์ชันการทำงานส่วนใหญ่มีความพิเศษ ปรับปรุง หรือเปลี่ยนแปลงโดยคลาสย่อย นี่คือคลาสย่อย รากฐานของการเขียนโปรแกรมเชิงวัตถุ วิธีการหรือตัวแปรส่วนตัวเป็นสิ่งจำเป็นในบางสถานการณ์ เช่น เมื่อคุณแน่ใจว่าคุณไม่ต้องการอนุญาตให้คลาสย่อยเปลี่ยนส่วนเฉพาะของคลาสพาเรนต์