Uma classe pode estender uma classe e implementar uma interface

100

Uma classe pode estender uma interface e outra classe em PHP?
Basicamente, eu quero fazer isso:

interface databaseInterface{
 public function query($q);
 public function escape($s);
 //more methods
}

class database{ //extends both mysqli and implements databaseInterface
 //etc.
}

Como alguém faria isso, simplesmente fazendo:

class database implements databaseInterface extends mysqli{ 

resulta em um erro fatal:

Erro de análise: erro de sintaxe, T_EXTENDS inesperados, esperando '{' em * arquivo * na linha * linha *
Pim Jager
fonte
18
Como isso é muito localizado ?! “Esta questão dificilmente ajudará futuros visitantes”. No entanto, a melhor resposta tem 33 votos positivos e a pergunta 4 estrelas!
dualidade_

Respostas:

177

Experimente o contrário:

class database extends mysqli implements databaseInterface { ...}

Isso deve funcionar.

Simon Lehmann
fonte
Ahh, muito obrigado. Por que exatamente eles deveriam ser o contrário?
Pim Jager,
14
Já que você só pode herdar uma classe e pode implementar qualquer número de interfaces, provavelmente era uma coisa de açúcar de sintaxe. Além disso, lembre-se, se sua subclasse implementa qualquer interface, isso também aparecerá na lista de métodos implementados. Portanto, colocá-los nessa ordem faz sentido.
Drew em
É uma prática ruim?
Mohammed Shamshid
21

Sim pode. Você só precisa manter a ordem correta.

class database extends mysqli implements databaseInterface { ... }

Além disso, uma classe pode implementar mais de uma interface. Apenas separe-os com vírgulas.

No entanto, sinto-me na obrigação de avisar que estender a classe mysqli é uma ideia incrivelmente ruim . Herança em si é provavelmente o conceito mais superestimado e mal utilizado na programação orientada a objetos.

Em vez disso, eu aconselho fazer coisas relacionadas ao banco de dados da maneira mysqli (ou maneira PDO).

Além disso, uma coisa pequena, mas as convenções de nomenclatura são importantes. Sua classe databaseparece mais geral então mysqli, portanto, sugere que o último herda de databasee não a maneira ao redor.

Michał Rudnicki
fonte
1
Por que estender a classe mysqli é uma má ideia?
Pim Jager,
11
Primeiro, porque não é seu. Quando os caras do mysqli decidem mudar algo, o comportamento da subclasse também muda. Em segundo lugar, a herança é usada para ESPECIALIZAR, não ESTENDER com funcionalidade extra. Essa é a coisa mais incompreendida em OOP. Como regra geral, tendo a estender apenas classes abstratas.
Michał Rudnicki
Michal - como uma mudança para mysqli seria diferente para um desenvolvedor que usa uma abordagem polimórfica versus uma agregada / composta? Você ainda teria que atualizar seu código para lidar com as mudanças.
Peter Bailey,
2
Estou familiarizado com o padrão do adaptador. Só estou dizendo que, se o nome de um método mudar ou se tornar obsoleto, você ainda precisará alterar o código em ambos os cenários. Embora eu concorde que uma abordagem não polimórfica seja melhor nesse cenário, não acredito que um adaptador seria "imune" a mudanças.
Peter Bailey,
2
Você só terá que alterar o código do adaptador, nem todos os lugares que usam esse código. Com a composição, você pode fornecer uma camada de compatibilidade de qualquer maneira, enquanto com a herança você pode chamá-la, na melhor das hipóteses, de um hack. E, estou corrigido, o adaptador forneceria melhor imunidade a alterações.
Michał Rudnicki
6

sim, na verdade, se você deseja implementar várias interfaces, pode fazer assim:

public class MyClass extends BaseClass implements myInterface1, myInterface2, myInterface3{ 

}
Ponteiro nulo
fonte