Existe alguma maneira de definir propriedades de classe abstrata no 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
fonte
fonte
Não, não há como impor isso ao compilador, você precisaria usar verificações em tempo de execução (digamos, no construtor) para a
$tablename
variável, por exemplo:Para impor isso a todas as classes derivadas de Foo_Abstract, você teria que criar o construtor de Foo_Abstract
final
, impedindo a substituição.Você pode declarar um getter abstrato:
fonte
Dependendo do contexto da propriedade, se desejar forçar a declaração de uma propriedade de objeto abstrato em um objeto filho, gosto de usar uma constante com a
static
palavra - chave para a propriedade nos métodos construtor de objeto abstrato ou métodos setter / getter. Opcionalmente, você pode usarfinal
para impedir que o método seja substituído em classes estendidas.Fora isso, o objeto filho substitui a propriedade e os métodos do objeto pai, se redefinidos. Por exemplo, se uma propriedade é declarada como
protected
no pai e redefinida comopublic
no filho, a propriedade resultante é pública. No entanto, se a propriedade for declaradaprivate
nos pais, ela permaneceráprivate
e não estará disponível para a criança.http://www.php.net//manual/en/language.oop5.static.php
fonte
Como afirmado acima, não existe uma definição exata. No entanto, eu uso essa solução alternativa simples para forçar a classe filho a definir a propriedade "abstrata":
fonte
static
propriedades.the only "safe" methods to have in a constructor are private and/or final ones
, não é minha solução alternativa nesse caso? im usando privates nele$name
. Você pode implementar asetName()
função sem que ela realmente esteja configurada$name
.getName
vez de$name
funciona melhor.abstract class Father { abstract protected function getName(); public function foo(){ echo $this->getName();} }
Fiz a mesma pergunta hoje e gostaria de adicionar meus dois centavos.
A razão pela qual gostaríamos de
abstract
propriedades é garantir que as subclasses as definam e gerem exceções quando não o fazem. No meu caso específico, eu precisava de algo que pudesse funcionar com umstatic
aliado.Idealmente, eu gostaria de algo assim:
Eu terminei com esta implementação
Como você pode ver, em
A
Eu não defino$prop
, mas eu o uso em umstatic
getter. Portanto, o código a seguir funcionaPor
C
outro lado, eu não defino$prop
, então recebo exceções:Devo ligar para o
getProp()
método para obter a exceção e não posso obtê-lo no carregamento de classe, mas é bastante próximo do comportamento desejado, pelo menos no meu caso.Defino
getProp()
comofinal
evitar que um cara esperto (eu mesmo em 6 meses) fique tentado a fazerfonte
Como você poderia ter descoberto testando seu código:
Não, não há. As propriedades não podem ser declaradas abstratas no PHP.
No entanto, você pode implementar um resumo da função getter / setter, isso pode ser o que você está procurando.
As propriedades não são implementadas (especialmente propriedades públicas), elas simplesmente existem (ou não):
fonte
A necessidade de propriedades abstratas pode indicar problemas de design. Enquanto muitas das respostas implementam o tipo de padrão do método Template e funcionem, sempre parece meio estranho.
Vamos dar uma olhada no exemplo original:
Marcar algo
abstract
é indicá-lo como algo indispensável. Bem, um valor obrigatório (neste caso) é uma dependência necessária, portanto deve ser passado ao construtor durante a instanciação :Então, se você realmente deseja uma classe nomeada mais concreta, pode herdar da seguinte maneira:
Isso pode ser útil se você usar o contêiner DI e precisar passar tabelas diferentes para objetos diferentes.
fonte
O PHP 7 facilita bastante a criação de "propriedades" abstratas. Assim como acima, você as cria criando funções abstratas, mas com o PHP 7 você pode definir o tipo de retorno para essa função, o que facilita muito as coisas ao criar uma classe base que qualquer pessoa pode estender.
fonte
se o valor do nome da tabela nunca for alterado durante a vida útil do objeto, a seguir será uma implementação simples, porém segura.
a chave aqui é que o valor da string 'users' é especificado e retornado diretamente em getTablename () na implementação da classe filho. A função imita uma propriedade "somente leitura".
Isso é bastante semelhante a uma solução publicada anteriormente, na qual usa uma variável adicional. Também gosto da solução de Marco, embora possa ser um pouco mais complicada.
fonte