Apakah ada cara untuk mendefinisikan properti kelas abstrak di PHP?
abstract class Foo_Abstract {
abstract public $tablename;
}
class Foo extends Foo_Abstract {
//Foo must 'implement' $property
public $tablename = 'users';
}
php
oop
abstract-class
Tamás Pap
sumber
sumber
Tidak, tidak ada cara untuk menegakkan itu dengan kompiler, Anda harus menggunakan pemeriksaan run-time (katakanlah, dalam konstruktor) untuk
$tablename
variabel, misalnya:Untuk menegakkan ini untuk semua kelas turunan Foo_Abstract Anda harus membuat konstruktor Foo_Abstract
final
, mencegah pengesampingan.Anda bisa mendeklarasikan pengambil abstrak:
sumber
Bergantung pada konteks properti jika saya ingin memaksakan deklarasi properti objek abstrak di objek anak, saya suka menggunakan konstanta dengan
static
kata kunci untuk properti di konstruktor objek abstrak atau metode setter / pengambil. Anda dapat menggunakan secara opsionalfinal
untuk mencegah metode ditimpa di kelas-kelas yang diperluas.Selain itu objek anak menimpa properti objek induk dan metode jika didefinisikan ulang. Misalnya jika properti dinyatakan sebagai
protected
di induk dan didefinisikan ulang sepertipublic
di anak, properti yang dihasilkan adalah publik. Namun, jika properti tersebut dinyatakanprivate
dalam induk, properti itu akan tetapprivate
dan tidak tersedia untuk anak.http://www.php.net//manual/en/language.oop5.static.php
sumber
Sebagaimana dinyatakan di atas, tidak ada definisi yang tepat. Namun, saya menggunakan solusi sederhana ini untuk memaksa kelas anak untuk mendefinisikan properti "abstrak":
sumber
static
properti.the only "safe" methods to have in a constructor are private and/or final ones
, bukankah penyelesaian masalah saya seperti itu? Saya menggunakan$name
. Anda dapat mengimplementasikansetName()
fungsi tanpa pengaturan yang sebenarnya$name
.getName
bukan$name
bekerja lebih baik.abstract class Father { abstract protected function getName(); public function foo(){ echo $this->getName();} }
Saya bertanya pada diri sendiri pertanyaan yang sama hari ini, dan saya ingin menambahkan dua sen saya.
Alasan kami ingin
abstract
properti adalah untuk memastikan bahwa subclass mendefinisikannya dan membuang pengecualian ketika mereka tidak. Dalam kasus khusus saya, saya membutuhkan sesuatu yang bisa bekerja denganstatic
sekutu.Idealnya saya ingin sesuatu seperti ini:
Saya berakhir dengan implementasi ini
Seperti yang Anda lihat, di
A
saya tidak mendefinisikan$prop
, tapi saya menggunakannya dalamstatic
pengambil. Oleh karena itu, kode berikut berfungsiDi
C
, di sisi lain, saya tidak mendefinisikan$prop
, jadi saya mendapatkan pengecualian:Saya harus memanggil
getProp()
metode untuk mendapatkan pengecualian dan saya tidak bisa mendapatkannya di pemuatan kelas, tetapi cukup dekat dengan perilaku yang diinginkan, setidaknya dalam kasus saya.Saya mendefinisikan
getProp()
sebagaifinal
untuk menghindari bahwa beberapa orang pintar (alias sendiri dalam 6 bulan) tergoda untuk melakukansumber
Seperti yang Anda ketahui dengan hanya menguji kode Anda:
Tidak, tidak ada. Properti tidak dapat dinyatakan abstrak dalam PHP.
Namun Anda dapat menerapkan fungsi getter / setter abstrak, ini mungkin yang Anda cari.
Properti tidak diimplementasikan (terutama properti publik), mereka hanya ada (atau tidak):
sumber
Kebutuhan akan properti abstrak dapat mengindikasikan masalah desain. Sementara banyak jawaban menerapkan jenis pola metode Templat dan itu berfungsi, itu selalu terlihat agak aneh.
Mari kita lihat contoh aslinya:
Menandai sesuatu
abstract
berarti menandainya sebagai sesuatu yang harus dimiliki. Nah, nilai yang harus dimiliki (dalam hal ini) adalah ketergantungan yang diperlukan, sehingga harus diteruskan ke konstruktor selama instantiasi :Maka jika Anda benar-benar menginginkan kelas bernama yang lebih konkret, Anda dapat mewarisi seperti:
Ini dapat berguna jika Anda menggunakan wadah DI dan harus melewati tabel berbeda untuk objek yang berbeda.
sumber
PHP 7 membuatnya sedikit lebih mudah untuk membuat "properti" abstrak. Sama seperti di atas, Anda akan membuatnya dengan membuat fungsi abstrak, tetapi dengan PHP 7 Anda dapat menentukan tipe pengembalian untuk fungsi itu, yang membuat segalanya jauh lebih mudah ketika Anda membangun kelas dasar yang dapat diperluas oleh siapa pun.
sumber
jika nilai tablename tidak akan pernah berubah selama masa hidup objek, mengikuti akan menjadi implementasi yang sederhana namun aman.
kuncinya di sini adalah bahwa nilai string 'pengguna' ditentukan dan dikembalikan langsung di getTablename () dalam implementasi kelas anak. Fungsi ini meniru properti "readonly".
Ini cukup mirip dengan solusi yang diposting sebelumnya yang menggunakan variabel tambahan. Saya juga suka solusi Marco meskipun bisa sedikit lebih rumit.
sumber