Existe-t-il un moyen de définir des propriétés de classe abstraites en 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
la source
la source
Non, il n'y a aucun moyen d'imposer cela avec le compilateur, vous devriez utiliser des vérifications au moment de l'exécution (par exemple, dans le constructeur) pour la
$tablename
variable, par exemple:Pour appliquer cela à toutes les classes dérivées de Foo_Abstract, vous devez créer le constructeur de Foo_Abstract, évitant ainsi le remplacement
final
.Vous pouvez plutôt déclarer un getter abstrait:
la source
En fonction du contexte de la propriété, si je veux forcer la déclaration d'une propriété d'objet abstrait dans un objet enfant, j'aime utiliser une constante avec le
static
mot - clé de la propriété dans le constructeur d'objet abstrait ou les méthodes setter / getter. Vous pouvez éventuellement utiliserfinal
pour empêcher la méthode d'être remplacée dans les classes étendues.À part cela, l'objet enfant remplace la propriété et les méthodes de l'objet parent s'il est redéfini. Par exemple, si une propriété est déclarée comme
protected
dans le parent et redéfinie commepublic
dans l'enfant, la propriété résultante est publique. Cependant, si la propriété est déclaréeprivate
dans le parent, elle resteraprivate
et ne sera pas disponible pour l'enfant.http://www.php.net//manual/en/language.oop5.static.php
la source
Comme indiqué ci-dessus, il n'existe pas de définition exacte. Cependant, j'utilise cette solution de contournement simple pour forcer la classe enfant à définir la propriété "abstract":
la source
static
propriétés.the only "safe" methods to have in a constructor are private and/or final ones
, ma solution de contournement n'est -elle pas un tel cas?$name
. Vous pouvez implémenter lasetName()
fonction sans qu'elle soit réellement définie$name
.getName
au lieu de$name
fonctionne mieux.abstract class Father { abstract protected function getName(); public function foo(){ echo $this->getName();} }
Je me suis posé la même question aujourd'hui et j'aimerais ajouter mes deux cents.
La raison pour laquelle nous aimerions des
abstract
propriétés est de nous assurer que les sous-classes les définissent et lèvent des exceptions quand elles ne le font pas. Dans mon cas précis, j'avais besoin de quelque chose qui pourrait fonctionner avec unstatic
allié.Idéalement, je voudrais quelque chose comme ceci:
J'ai fini avec cette implémentation
Comme vous pouvez le voir, dans
A
je ne définit pas$prop
, mais je l'utilise dans unstatic
getter. Par conséquent, le code suivant fonctionneEn
C
, par contre, je ne définit pas$prop
, donc j'obtiens des exceptions:Je dois appeler la
getProp()
méthode pour obtenir l'exception et je ne peux pas l'obtenir lors du chargement de la classe, mais c'est assez proche du comportement souhaité, du moins dans mon cas.Je définis
getProp()
commefinal
éviter qu'un mec intelligent (alias moi-même dans 6 mois) soit tenté de fairela source
Comme vous auriez pu le découvrir en testant simplement votre code:
Non, il n'y en a pas. Les propriétés ne peuvent pas être déclarées abstraites en PHP.
Cependant, vous pouvez implémenter un résumé de la fonction getter / setter, c'est peut-être ce que vous recherchez.
Les propriétés ne sont pas implémentées (en particulier les propriétés publiques), elles existent juste (ou non):
la source
Le besoin de propriétés abstraites peut indiquer des problèmes de conception. Bien que de nombreuses réponses implémentent une sorte de modèle de méthode Template et que cela fonctionne, cela semble toujours étrange.
Jetons un coup d'œil à l'exemple original:
Marquer quelque chose,
abstract
c'est l'indiquer comme un incontournable. Eh bien, une valeur indispensable (dans ce cas) est une dépendance obligatoire, elle doit donc être transmise au constructeur lors de l'instanciation :Ensuite, si vous voulez réellement une classe nommée plus concrète, vous pouvez hériter comme suit:
Cela peut être utile si vous utilisez un conteneur DI et devez passer différentes tables pour différents objets.
la source
PHP 7 facilite un peu la création de "propriétés" abstraites. Tout comme ci-dessus, vous les ferez en créant des fonctions abstraites, mais avec PHP 7, vous pouvez définir le type de retour pour cette fonction, ce qui facilite beaucoup les choses lorsque vous créez une classe de base que tout le monde peut étendre.
la source
si la valeur de nom_table ne changera jamais pendant la durée de vie de l'objet, la suite sera une implémentation simple mais sûre.
la clé ici est que la valeur de chaîne 'users' est spécifiée et renvoyée directement dans getTablename () dans l'implémentation de la classe enfant. La fonction imite une propriété "lecture seule".
Ceci est assez similaire à une solution publiée précédemment sur qui utilise une variable supplémentaire. J'aime aussi la solution de Marco même si elle peut être un peu plus compliquée.
la source