Dapatkah sebuah kelas memperluas kelas dan mengimplementasikan Antarmuka

100

Bisakah sebuah kelas memperluas antarmuka dan kelas lain dalam PHP?
Pada dasarnya saya ingin melakukan ini:

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

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

Bagaimana seseorang melakukan ini, hanya melakukan:

class database implements databaseInterface extends mysqli{ 

mengakibatkan kesalahan fatal:

Kesalahan Parse: kesalahan sintaks, T_EXTENDS tak terduga, mengharapkan '{' dalam * file * pada baris * baris *
Pim Jager
sumber
18
Bagaimana ini terlalu terlokalisasi ?! "Pertanyaan ini sepertinya tidak akan membantu pengunjung di masa mendatang". Namun jawaban terbaik memiliki 33 suara positif dan pertanyaan 4 bintang!
dualitas_

Jawaban:

177

Coba sebaliknya:

class database extends mysqli implements databaseInterface { ...}

Ini seharusnya berhasil.

Simon Lehmann
sumber
Ahh, terima kasih banyak. Mengapa tepatnya mereka harus sebaliknya?
Pim Jager
14
Karena Anda hanya dapat mewarisi satu kelas dan Anda dapat mengimplementasikan sejumlah antarmuka, itu mungkin hal gula sintaks. Juga, ingat, jika subclass Anda mengimplementasikan antarmuka apa pun, itu juga akan muncul dalam daftar metode yang diimplementasikan. Jadi, menempatkannya dalam urutan itu masuk akal.
Mundur
Apakah ini praktik yang buruk?
Mohammed Shamshid
21

Ya bisa. Anda hanya perlu mempertahankan urutan yang benar.

class database extends mysqli implements databaseInterface { ... }

Selain itu, sebuah kelas dapat mengimplementasikan lebih dari satu antarmuka. Pisahkan saja dengan koma.

Namun, saya merasa berkewajiban untuk memperingatkan Anda bahwa memperluas kelas mysqli adalah ide yang sangat buruk . Warisan per se mungkin merupakan konsep yang paling dilebih-lebihkan dan disalahgunakan dalam pemrograman berorientasi objek.

Sebaliknya saya menyarankan melakukan hal-hal yang berhubungan dengan db dengan cara mysqli (atau cara PDO).

Plus, hal kecil, tetapi konvensi penamaan itu penting. Kelas Andadatabase tampaknya lebih umum mysqli, oleh karena itu hal itu menunjukkan bahwa yang terakhir mewarisi dari databasedan bukan sebaliknya.

Michał Rudnicki
sumber
1
Mengapa memperluas kelas mysqli adalah ide yang buruk?
Pim Jager
11
Pertama, karena itu bukan milikmu. Ketika teman-teman mysqli memutuskan untuk mengubah sesuatu, perilaku subclass juga akan berubah. Kedua, inheritance digunakan untuk SPECIALIZE, bukan EXTEND dengan fungsionalitas ekstra. Ini adalah hal yang paling disalahpahami di OOP. Sebagai aturan praktis, saya cenderung hanya memperluas kelas abstrak.
Michał Rudnicki
Michal - bagaimana perubahan pada mysqli menjadi berbeda untuk pengembang yang menggunakan pendekatan polimorfik vs yang dikumpulkan / dibuat? Anda masih harus memperbarui kode Anda untuk menangani perubahan.
Peter Bailey
2
Saya terbiasa dengan pola adaptor. Saya hanya mengatakan bahwa jika nama metode berubah atau tidak digunakan lagi, Anda masih perlu mengubah kode di kedua skenario. Meskipun saya setuju bahwa pendekatan non-polimorfik lebih baik dalam skenario ini, saya tidak membeli gagasan bahwa adaptor akan "kebal" untuk berubah.
Peter Bailey
2
Anda hanya perlu mengubah kode adaptor, tidak semua tempat menggunakan kode itu. Dengan komposisi, Anda dapat memberikan lapisan kompatibilitas apa pun yang terjadi, sedangkan dengan warisan, Anda dapat menyebutnya sebagai peretasan. Dan, saya yakin, adaptor akan memberikan kekebalan yang lebih baik untuk berubah.
Michał Rudnicki
6

ya, sebenarnya jika Anda ingin mengimplementasikan banyak antarmuka, Anda dapat melakukan seperti ini:

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

}
nullpointer
sumber