¿Hay alguna forma de definir propiedades de clase abstracta 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
fuente
fuente
No, no hay forma de aplicar eso con el compilador, tendría que usar verificaciones en tiempo de ejecución (por ejemplo, en el constructor) para la
$tablename
variable, por ejemplo:Para hacer cumplir esto para todas las clases derivadas de Foo_Abstract, tendría que hacer el constructor de Foo_Abstract
final
, evitando la anulación.En su lugar, podría declarar un captador abstracto:
fuente
Dependiendo del contexto de la propiedad si quiero forzar la declaración de una propiedad de objeto abstracto en un objeto hijo, me gusta usar una constante con la
static
palabra clave para la propiedad en el constructor de objetos abstractos o métodos setter / getter. Opcionalmente, puede usarfinal
para evitar que el método se anule en clases extendidas.Aparte de eso, el objeto secundario anula la propiedad y los métodos del objeto principal si se redefine. Por ejemplo, si una propiedad se declara como
protected
en el padre y se redefine comopublic
en el hijo, la propiedad resultante es pública. Sin embargo, si la propiedad se declaraprivate
en el padre, permaneceráprivate
y no estará disponible para el niño.http://www.php.net//manual/en/language.oop5.static.php
fuente
Como se indicó anteriormente, no existe tal definición exacta. Sin embargo, utilizo esta solución simple para forzar a la clase secundaria a definir la propiedad "abstracta":
fuente
static
propiedades.the only "safe" methods to have in a constructor are private and/or final ones
, ¿no es mi solución este caso? estoy usando$name
. Puede implementar lasetName()
función sin que realmente se configure$name
.getName
lugar de$name
funciona mejor.abstract class Father { abstract protected function getName(); public function foo(){ echo $this->getName();} }
Hoy me hice la misma pregunta y me gustaría agregar mis dos centavos.
La razón por la que nos gustaría tener
abstract
propiedades es para asegurarnos de que las subclases las definan y arrojen excepciones cuando no lo hacen. En mi caso específico, necesitaba algo que pudiera funcionar constatic
aliado.Idealmente me gustaría algo como esto:
Terminé con esta implementación
Como puede ver, en
A
No lo defino$prop
, pero lo uso en unstatic
captador. Por lo tanto, el siguiente código funcionaEn
C
, por otro lado, no defino$prop
, por lo que obtengo excepciones:Debo llamar al
getProp()
método para obtener la excepción y no puedo obtenerlo al cargar la clase, pero está bastante cerca del comportamiento deseado, al menos en mi caso.Defino
getProp()
comofinal
evitar que algún tipo inteligente (también conocido como yo en 6 meses) tenga la tentación de hacerfuente
Como podría haber descubierto simplemente probando su código:
No no hay. Las propiedades no pueden declararse abstractas en PHP.
Sin embargo, puede implementar un resumen de la función getter / setter, esto podría ser lo que está buscando.
Las propiedades no se implementan (especialmente las propiedades públicas), solo existen (o no):
fuente
La necesidad de propiedades abstractas puede indicar problemas de diseño. Si bien muchas de las respuestas implementan un tipo de patrón de método de Plantilla y funciona, siempre parece un poco extraño.
Echemos un vistazo al ejemplo original:
Marcar algo
abstract
es indicarlo como algo imprescindible. Bueno, un valor imprescindible (en este caso) es una dependencia requerida, por lo que debe pasarse al constructor durante la creación de instancias :Entonces, si realmente desea una clase con nombre más concreta, puede heredar así:
Esto puede ser útil si usa el contenedor DI y tiene que pasar diferentes tablas para diferentes objetos.
fuente
PHP 7 lo hace bastante más fácil para hacer "propiedades" abstractas. Al igual que anteriormente, los creará creando funciones abstractas, pero con PHP 7 puede definir el tipo de retorno para esa función, lo que facilita mucho las cosas cuando construye una clase base que cualquiera puede ampliar.
fuente
si el valor del nombre de la tabla nunca cambiará durante la vida útil del objeto, la siguiente será una implementación simple pero segura.
La clave aquí es que el valor de cadena 'usuarios' se especifica y se devuelve directamente en getTablename () en la implementación de la clase secundaria. La función imita una propiedad de "solo lectura".
Esto es bastante similar a una solución publicada anteriormente que utiliza una variable adicional. También me gusta la solución de Marco, aunque puede ser un poco más complicada.
fuente