คลาสสามารถขยายทั้งคลาสและใช้อินเทอร์เฟซได้


100

คลาสสามารถขยายทั้งอินเทอร์เฟซและคลาสอื่นใน PHP ได้หรือไม่
โดยทั่วไปฉันต้องการทำสิ่งนี้:

interface databaseInterface{
 public function query($q);
 public function escape($s);
 //more methods
}

class database{ //extends both mysqli and implements databaseInterface
 //etc.
}

จะทำอย่างไรเพียงแค่ทำ:

class database implements databaseInterface extends mysqli{ 

ส่งผลให้เกิดข้อผิดพลาดร้ายแรง:

ข้อผิดพลาดในการแยกวิเคราะห์: ข้อผิดพลาดทางไวยากรณ์ T_EXTENDS ที่ไม่คาดคิดคาดหวัง "{" ใน * ไฟล์ * ในบรรทัด * บรรทัด *

18
มันแปลมากเกินไปได้อย่างไร! "คำถามนี้ไม่น่าจะช่วยผู้เยี่ยมชมในอนาคตได้" คำตอบที่ดีที่สุดมี 33 โหวตและคำถาม 4 ดาว!
duality_

คำตอบ:


177

ลองในทางกลับกัน:

class database extends mysqli implements databaseInterface { ...}

สิ่งนี้ควรใช้งานได้


อ่าขอบคุณมาก ทำไมพวกเขาถึงควรเป็นอีกทางหนึ่ง?
Pim Jager

14
เนื่องจากคุณสามารถสืบทอดคลาสได้เพียงคลาสเดียวและคุณสามารถใช้อินเทอร์เฟซจำนวนเท่าใดก็ได้จึงน่าจะเป็นเรื่องน้ำตาลของไวยากรณ์ นอกจากนี้โปรดจำไว้ว่าหากคลาสย่อยของคุณใช้อินเทอร์เฟซใด ๆ สิ่งนั้นจะปรากฏในรายการวิธีการใช้งานด้วย ดังนั้นการวางไว้ในลำดับนั้นจึงสมเหตุสมผล
Drew

เป็นการปฏิบัติที่ไม่ดีหรือไม่?
Mohammed Shamshid

21

ใช่มันทำได้ คุณเพียงแค่ต้องรักษาลำดับที่ถูกต้อง

class database extends mysqli implements databaseInterface { ... }

ยิ่งไปกว่านั้นคลาสสามารถใช้งานได้มากกว่าหนึ่งอินเทอร์เฟซ เพียงคั่น 'em ด้วยลูกน้ำ

แต่ผมรู้สึกว่าหน้าที่ที่จะเตือนคุณว่าการขยายชั้นเรียน mysqli เป็นความคิดที่ดีอย่างไม่น่าเชื่อ การสืบทอดต่อ se น่าจะเป็นแนวคิดที่เกินจริงและถูกนำไปใช้ในทางที่ผิดในการเขียนโปรแกรมเชิงวัตถุ

ฉันแนะนำให้ทำสิ่งที่เกี่ยวข้องกับ db ด้วยวิธี mysqli (หรือวิธี PDO)

นอกจากนี้สิ่งเล็กน้อย แต่หลักการตั้งชื่อมีความสำคัญ ชั้นเรียนของคุณdatabaseดูกว้างขึ้นmysqliดังนั้นจึงชี้ให้เห็นว่าชั้นเรียนนั้นสืบทอดมาจากdatabaseไม่ใช่ทางรอบ ๆ


1
เหตุใดการขยายคลาส mysqli จึงเป็นความคิดที่ไม่ดี
Pim Jager

11
อันดับแรกเพราะไม่ใช่ของคุณ เมื่อพวก mysqli ตัดสินใจเปลี่ยนพฤติกรรมของคลาสย่อยก็จะเปลี่ยนไปเช่นกัน ประการที่สองการสืบทอดถูกใช้เพื่อพิเศษไม่ใช่เพิ่มฟังก์ชันพิเศษ นี่คือสิ่งที่เข้าใจผิดที่สุดใน OOP ตามกฎทั่วไปฉันมักจะขยายคลาสนามธรรมเท่านั้น
Michał Rudnicki

Michal - การเปลี่ยนแปลง mysqli จะแตกต่างกันอย่างไรสำหรับนักพัฒนาที่ใช้วิธีการหลายรูปแบบกับวิธีการรวม / ประกอบด้วย คุณยังต้องอัปเดตรหัสของคุณเพื่อจัดการกับการเปลี่ยนแปลง
Peter Bailey

2
ฉันคุ้นเคยกับรูปแบบอะแดปเตอร์ ฉันแค่บอกว่าถ้าชื่อเมธอดเปลี่ยนไปหรือเลิกใช้งานคุณจะยังต้องเปลี่ยนโค้ดในทั้งสองสถานการณ์ แม้ว่าฉันจะยอมรับว่าวิธีการที่ไม่ใช่รูปแบบหลายรูปแบบนั้นดีกว่าในสถานการณ์นี้ แต่ฉันไม่ได้ซื้อแนวคิดที่ว่าอะแดปเตอร์จะ "ภูมิคุ้มกัน" ที่จะเปลี่ยนแปลง
Peter Bailey

2
คุณจะต้องเปลี่ยนรหัสอะแดปเตอร์เท่านั้นไม่ใช่ทุกสถานที่ที่ใช้รหัสนั้น ด้วยองค์ประกอบคุณสามารถจัดเตรียมเลเยอร์ความเข้ากันได้ไม่ว่าจะเป็นอย่างไรในขณะที่การสืบทอดคุณสามารถเรียกมันว่าแฮ็คได้ดีที่สุด และฉันได้รับการแก้ไขแล้วอะแดปเตอร์จะให้ภูมิคุ้มกันที่ดีขึ้นในการเปลี่ยนแปลง
Michał Rudnicki

6

ใช่ในความเป็นจริงหากคุณต้องการใช้อินเทอร์เฟซหลายตัวคุณสามารถทำได้ดังนี้:

public class MyClass extends BaseClass implements myInterface1, myInterface2, myInterface3{ 

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.