Gibt es eine Möglichkeit, abstrakte Klasseneigenschaften in PHP zu definieren?
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
quelle
quelle
Nein, es gibt keine Möglichkeit, dies zu erzwingen. Mit dem Compiler müssten Sie Laufzeitprüfungen (
$tablename
z. B. im Konstruktor) für die Variable verwenden, z.Um dies für alle abgeleiteten Klassen von Foo_Abstract zu erzwingen, müssten Sie den Konstruktor von Foo_Abstract erstellen, um ein Überschreiben zu
final
verhindern.Sie könnten stattdessen einen abstrakten Getter deklarieren:
quelle
Abhängig vom Kontext der Eigenschaft, wenn ich die Deklaration einer abstrakten Objekteigenschaft in einem untergeordneten Objekt erzwingen möchte, verwende ich gerne eine Konstante mit dem
static
Schlüsselwort für die Eigenschaft im abstrakten Objektkonstruktor oder in den Setter / Getter-Methoden. Sie können optional verwendenfinal
, um zu verhindern, dass die Methode in erweiterten Klassen überschrieben wird.Ansonsten überschreibt das untergeordnete Objekt die übergeordneten Objekteigenschaften und -methoden, wenn es neu definiert wird. Wenn beispielsweise eine Eigenschaft wie
protected
im übergeordneten Element deklariert und wie im untergeordneten Element neu definiert wirdpublic
, ist die resultierende Eigenschaft öffentlich. Wenn die Eigenschaft jedochprivate
im übergeordneten Element deklariert ist, bleibt sie erhaltenprivate
und steht dem untergeordneten Element nicht zur Verfügung.http://www.php.net//manual/en/language.oop5.static.php
quelle
Wie oben erwähnt, gibt es keine so genaue Definition. Ich verwende diese einfache Problemumgehung jedoch, um die untergeordnete Klasse zu zwingen, die "abstrakte" Eigenschaft zu definieren:
quelle
static
Immobilien nicht.the only "safe" methods to have in a constructor are private and/or final ones
, ist meine Problemumgehung nicht so ein Fall?$name
. Sie können diesetName()
Funktion implementieren , ohne sie tatsächlich einzustellen$name
.getName
anstelle von$name
besser funktioniert.abstract class Father { abstract protected function getName(); public function foo(){ echo $this->getName();} }
Ich habe mir heute die gleiche Frage gestellt und möchte meine zwei Cent hinzufügen.
Der Grund, warum wir
abstract
Eigenschaften wünschen, besteht darin, sicherzustellen, dass Unterklassen sie definieren und Ausnahmen auslösen, wenn dies nicht der Fall ist. In meinem speziellen Fall brauchte ich etwas, das mitstatic
Verbündeten zusammenarbeiten konnte.Idealerweise möchte ich so etwas:
Am Ende war ich bei dieser Implementierung
Wie Sie sehen können,
A
definiere ich in nicht$prop
, aber ich benutze es in einemstatic
Getter. Daher funktioniert der folgende CodeIn
C
, auf der anderen Seite, ich nicht definieren$prop
, so dass ich Ausnahmen erhalten:Ich muss die
getProp()
Methode aufrufen , um die Ausnahme zu erhalten, und ich kann sie beim Laden der Klasse nicht erhalten, aber sie kommt zumindest in meinem Fall dem gewünschten Verhalten ziemlich nahe.Ich sehe ,
getProp()
wiefinal
zu vermeiden , dass einige smart guy (aka mich in 6 Monaten) ist versucht zu tunquelle
Wie Sie durch einfaches Testen Ihres Codes hätten herausfinden können:
Nein, da ist kein. Eigenschaften können in PHP nicht als abstrakt deklariert werden.
Sie können jedoch eine Zusammenfassung der Getter- / Setter-Funktion implementieren. Dies ist möglicherweise das, wonach Sie suchen.
Eigenschaften sind nicht implementiert (insbesondere öffentliche Eigenschaften), sie existieren nur (oder nicht):
quelle
Die Notwendigkeit abstrakter Eigenschaften kann auf Entwurfsprobleme hinweisen. Während viele Antworten eine Art Template-Methodenmuster implementieren und es funktioniert, sieht es immer irgendwie seltsam aus.
Schauen wir uns das ursprüngliche Beispiel an:
Etwas zu markieren
abstract
bedeutet, es als ein Muss anzuzeigen. Nun, ein Must-Have-Wert (in diesem Fall) ist eine erforderliche Abhängigkeit, daher sollte er während der Instanziierung an den Konstruktor übergeben werden :Wenn Sie dann tatsächlich eine konkretere benannte Klasse möchten, können Sie wie folgt erben:
Dies kann nützlich sein, wenn Sie DI-Container verwenden und unterschiedliche Tabellen für unterschiedliche Objekte übergeben müssen.
quelle
PHP 7 erleichtert das Erstellen abstrakter "Eigenschaften" erheblich. Wie oben werden Sie sie erstellen, indem Sie abstrakte Funktionen erstellen. Mit PHP 7 können Sie jedoch den Rückgabetyp für diese Funktion definieren. Dies erleichtert die Erstellung einer Basisklasse, die jeder erweitern kann, erheblich.
quelle
Wenn sich der Wert des Tabellennamens während der Lebensdauer des Objekts niemals ändert, folgt eine einfache, aber sichere Implementierung.
Der Schlüssel hier ist, dass der Zeichenfolgenwert 'users' angegeben und direkt in getTablename () in der Implementierung der untergeordneten Klasse zurückgegeben wird. Die Funktion ahmt eine "schreibgeschützte" Eigenschaft nach.
Dies ist einer zuvor veröffentlichten Lösung ziemlich ähnlich, bei der eine zusätzliche Variable verwendet wird. Ich mag auch Marcos Lösung, obwohl sie etwas komplizierter sein kann.
quelle