Pergunta

Interfaces permitem que você crie código que defina os métodos das classes que o implementam.No entanto, você não pode adicionar nenhum código a esses métodos.

Aulas abstratas permitem que você faça a mesma coisa, além de adicionar código ao método.

Agora, se você pode atingir o mesmo objetivo com classes abstratas, por que precisamos do conceito de interfaces?

Disseram-me que isso tem a ver com a teoria OO de C++ a Java, que é a base do material OO do PHP.O conceito é útil em Java, mas não em PHP?É apenas uma maneira de evitar espaços reservados espalhados pela classe abstrata?Estou esquecendo de algo?

Foi útil?

Solução

O objetivo das interfaces é fornecer flexibilidade para que sua classe seja forçada a implementar múltiplas interfaces, mas ainda assim não permitir herança múltipla.Os problemas com a herança de múltiplas classes são muitos e variados e o Wikipédia página resume-os muito bem.

As interfaces são um compromisso.A maioria dos problemas com herança múltipla não se aplica a classes base abstratas, portanto, a maioria das linguagens modernas hoje em dia desativa a herança múltipla, mas chama interfaces de classes base abstratas e permite que uma classe "implemente" quantas quiser.

Outras dicas

O conceito é útil em toda a programação orientada a objetos.Para mim, penso em uma interface como um contrato.Contanto que minha classe e sua classe concordem com este contrato de assinatura de método, podemos "interfacear".Quanto às classes abstratas, vejo-as mais como classes base que eliminam alguns métodos e preciso preencher os detalhes.

Por que você precisaria de uma interface, se já existem classes abstratas?Para evitar herança múltipla (pode causar vários problemas conhecidos).

Um desses problemas:

O "problema de diamante" (às vezes chamado de "diamante mortal da morte") é uma ambiguidade que surge quando duas classes B e C herdam de A e Classe D herda de B e C.Se houver um método em A que B e C substituíram, e D não o substitui, qual versão do método D herda:o de B ou o de C?

Fonte: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem

Por que/quando usar uma interface?Um exemplo...Todos os carros do mundo têm a mesma interface (métodos)... AccelerationPedalIsOnTheRight(), BrakePedalISOnTheLeft().Imagine que cada marca de carro teria esses “métodos” diferentes de outra marca.A BMW teria os freios do lado direito e a Honda teria os freios do lado esquerdo do volante.As pessoas teriam que aprender como esses “métodos” funcionam toda vez que comprassem uma marca diferente de carro.É por isso que é uma boa ideia ter a mesma interface em vários “locais”.

O que uma interface faz por você (por que alguém usaria uma)?Uma interface evita que você cometa "erros" (garante que todas as classes que implementam uma interface específica terão os métodos que estão na interface).

// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{   
    public function Create($personObject);
}

class MySqlPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Create a new person in MySql database.
    }
}

class MongoPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
    }
}

Desta forma, o Create() método será sempre usado da mesma maneira.Não importa se estamos usando o MySqlPerson classe ou o MongoPerson aula.A forma como usamos um método permanece a mesma (a interface permanece a mesma).

Por exemplo, será usado assim (em todo o nosso código):

new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);

Dessa forma, algo assim não pode acontecer:

new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);

É muito mais fácil lembrar de uma interface e usar a mesma em qualquer lugar do que várias interfaces diferentes.

Desta forma, o interior do Create() O método pode ser diferente para classes diferentes, sem afetar o código "externo", que chama esse método.Tudo o que o código externo precisa saber é que o método Create() tem 1 parâmetro ($personObject), porque é assim que o código externo usará/chamará o método.O código externo não se importa com o que está acontecendo dentro do método;basta saber usá-lo/chamá-lo.

Você também pode fazer isso sem interface, mas se usar uma interface, é "mais seguro" (porque evita que você cometa erros).A interface garante que o método Create() terá a mesma assinatura (mesmos tipos e mesmo número de parâmetros) em todas as classes que implementam a interface.Dessa forma, você pode ter certeza de que QUALQUER classe que implemente o IPersonService interface, terá o método Create() (neste exemplo) e precisará de apenas 1 parâmetro ($personObject) para ser chamado/usado.

Uma classe que implementa uma interface deve implementar todos os métodos que a interface faz/possui.

Espero não ter me repetido muito.

Para mim, a diferença entre usar uma interface e uma classe abstrata tem mais a ver com a organização do código do que com a aplicação pela própria linguagem.Eu os uso muito ao preparar código para outros desenvolvedores trabalharem, para que permaneçam dentro dos padrões de design pretendidos.As interfaces são uma espécie de "projeto por contrato", em que seu código concorda em responder a um conjunto prescrito de chamadas de API que podem vir de um código ao qual você não tem acesso.

Embora a herança da classe abstrata seja uma relação "é uma", nem sempre é isso que você deseja, e implementar uma interface é mais uma relação "age como uma".Essa diferença pode ser bastante significativa em determinados contextos.

Por exemplo, digamos que você tenha uma classe abstrata Account da qual muitas outras classes se estendem (tipos de contas e assim por diante).Possui um conjunto específico de métodos que são aplicáveis ​​apenas a esse grupo de tipos.No entanto, algumas dessas subclasses de conta implementam Versionable, Listable ou Editable para que possam ser lançadas em controladores que esperam usar essas APIs.O controlador não se importa com o tipo de objeto

Por outro lado, também posso criar um objeto que não se estenda de Account, digamos, uma classe abstrata User, e ainda implementar Listable e Editable, mas não Versionable, o que não faz sentido aqui.

Desta forma, estou dizendo que a subclasse FooUser NÃO é uma conta, mas age como um objeto editável.Da mesma forma, BarAccount se estende de Account, mas não é uma subclasse de User, mas implementa Editable, Listable e também Versionable.

Adicionar todas essas APIs para Editável, Listável e Versionável nas próprias classes abstratas não seria apenas confuso e feio, mas também duplicaria as interfaces comuns em Conta e Usuário ou forçaria meu objeto Usuário a implementar Versionável, provavelmente apenas para lançar um exceção.

As interfaces são essencialmente um modelo do que você pode criar.Eles definem quais métodos uma classe deve ter, mas você pode criar métodos extras fora dessas limitações.

Não tenho certeza do que você quer dizer com não poder adicionar código aos métodos - porque você pode.Você está aplicando a interface a uma classe abstrata ou à classe que a estende?

Um método na interface aplicado à classe abstrata precisará ser implementado nessa classe abstrata.No entanto, aplique essa interface à classe de extensão e o método só precisará ser implementado na classe de extensão.Posso estar errado aqui - não uso interfaces com a frequência que poderia/deveria.

Sempre pensei nas interfaces como um padrão para desenvolvedores externos ou um conjunto de regras extra para garantir que tudo esteja correto.

Você usará interfaces em PHP:

  1. Para ocultar a implementação - estabeleça um protocolo de acesso a uma classe de objetos e altere a implementação subjacente sem refatorar em todos os locais em que você usou esses objetos
  2. Para verificar o tipo - como garantir que um parâmetro tenha um tipo específico $object instanceof MyInterface
  3. Para impor a verificação de parâmetros em tempo de execução
  4. Para implementar vários comportamentos em uma única classe (construir tipos complexos)

    class Carro implementa EngineInterface, BodyInterface, SteeringInterface {

para que um Car objeto ca agora start(), stop() (EngineInterface) ou goRight(),goLeft() (Interface de direção)

e outras coisas que não consigo pensar agora

Número 4 é provavelmente o caso de uso mais óbvio que você não pode resolver com classes abstratas.

Do Pensando em Java:

Uma interface diz: "É assim que todas as classes que implementam essa interface em particular serão". Assim, qualquer código que use uma interface específico sabe quais métodos podem ser chamados para essa interface, e isso é tudo.Portanto a interface é utilizada para estabelecer um “protocolo” entre classes.

As interfaces existem não como uma base sobre a qual as classes podem se estender, mas como um mapa de funções necessárias.

A seguir está um exemplo de uso de uma interface onde uma classe abstrata não cabe:
Digamos que eu tenha um aplicativo de calendário que permite aos usuários importar dados de calendário de fontes externas.Eu escreveria classes para lidar com a importação de cada tipo de fonte de dados (ical, rss, atom, json). Cada uma dessas classes implementaria uma interface comum que garantiria que todas tivessem os métodos públicos comuns que meu aplicativo precisa para obter os dados.

<?php

interface ImportableFeed 
{
    public function getEvents();
}

Então, quando um usuário adiciona um novo feed, posso identificar o tipo de feed e usar a classe desenvolvida para esse tipo para importar os dados.Cada classe escrita para importar dados para um feed específico teria um código completamente diferente; caso contrário, poderia haver muito poucas semelhanças entre as classes, fora o fato de que elas são necessárias para implementar a interface que permite que meu aplicativo as consuma.Se eu usasse uma classe abstrata, poderia facilmente ignorar o fato de não ter substituído o método getEvents(), o que interromperia meu aplicativo nesta instância, enquanto o uso de uma interface não permitiria que meu aplicativo fosse executado se QUALQUER um dos métodos definidos na interface não existem na classe que o implementou.Meu aplicativo não precisa se preocupar com qual classe ele usa para obter dados de um feed, apenas com os métodos necessários para obter esses dados.

Para dar um passo adiante, a interface se mostra extremamente útil quando volto ao meu aplicativo de calendário com a intenção de adicionar outro tipo de feed.Usar a interface ImportableFeed significa que posso continuar adicionando mais classes que importam diferentes tipos de feed simplesmente adicionando novas classes que implementam essa interface.Isso me permite adicionar toneladas de funcionalidades sem ter que adicionar volume desnecessário ao meu aplicativo principal, já que meu aplicativo principal depende apenas da existência de métodos públicos disponíveis que a interface exige, desde que minhas novas classes de importação de feed implementem a interface ImportableFeed, então eu sei que posso simplesmente colocá-lo no lugar e seguir em frente.

Este é apenas um começo muito simples.Posso então criar outra interface que todas as minhas classes de calendário possam implementar, oferecendo mais funcionalidades específicas para o tipo de feed que a classe manipula.Outro bom exemplo seria um método para verificar o tipo de feed, etc.

Isso vai além da questão, mas já que usei o exemplo acima:As interfaces apresentam seu próprio conjunto de problemas se usadas dessa maneira.Eu preciso garantir que a saída retornada dos métodos implementados corresponda à interface e para conseguir isso eu uso um IDE que lê blocos PHPDoc e adiciono o tipo de retorno como uma dica de tipo em um bloco PHPDoc da interface que irá então traduza para a classe concreta que o implementa.Minhas classes que consomem a saída de dados das classes que implementam essa interface saberão, no mínimo, que estão esperando um array retornado neste exemplo:

<?php
interface ImportableFeed 
{
    /**
     * @return array
     */
    public function getEvents();
}

Não há muito espaço para comparar classes e interfaces abstratas.Interfaces são simplesmente mapas que, quando implementados, exigem que a classe tenha um conjunto de interfaces públicas.

As interfaces não servem apenas para garantir que os desenvolvedores implementem determinados métodos.A idéia é que, como é garantido que essas classes tenham determinados métodos, você possa usá-los mesmo que não conheça o tipo real da classe.Exemplo:

interface Readable {
  String read();
}

List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
  System.out.println(reader.read());

Em muitos casos, não faz sentido fornecer uma classe base, abstrata ou não, porque as implementações variam muito e não compartilham nada em comum além de alguns métodos.

Linguagens digitadas dinamicamente têm a noção de "digitação de pato", onde você não precisa de interfaces;você está livre para assumir que o objeto possui o método que você está chamando.Isso contorna o problema em linguagens de tipo estaticamente onde seu objeto possui algum método (no meu exemplo, read()), mas não implementa a interface.

Na minha opinião, as interfaces devem ser preferidas às classes abstratas não funcionais.Eu não ficaria surpreso se houvesse um impacto no desempenho, já que há apenas um objeto instanciado, em vez de analisar dois, combinando-os (embora não tenha certeza, não estou familiarizado com o funcionamento interno de POO PHP).

É verdade que as interfaces são menos úteis/significativas do que comparadas, digamos, com Java.Por outro lado, o PHP6 introduzirá ainda mais dicas de tipo, incluindo dicas de tipo para valores de retorno.Isso deve agregar algum valor às interfaces PHP.

dr:interfaces define uma lista de métodos que precisam ser seguidos (pense em API), enquanto uma classe abstrata fornece algumas funcionalidades básicas/comuns, que as subclasses refinam para necessidades específicas.

Não me lembro se o PHP é diferente nesse aspecto, mas em Java você pode implementar várias interfaces, mas não pode herdar várias classes abstratas.Eu diria que o PHP funciona da mesma maneira.

Em PHP você pode aplicar múltiplas interfaces separando-as com uma vírgula (acho que não acho isso uma solução limpa).

Quanto a múltiplas classes abstratas, você poderia ter vários resumos estendendo-se uns aos outros (novamente, não tenho certeza disso, mas acho que já vi isso em algum lugar antes).A única coisa que você não pode estender é uma aula final.

As interfaces não darão ao seu código nenhum aumento de desempenho ou algo parecido, mas podem contribuir muito para torná-lo sustentável.É verdade que uma classe abstrata (ou mesmo uma classe não abstrata) pode ser usada para estabelecer uma interface para o seu código, mas interfaces adequadas (aquelas que você define com a palavra-chave e que contêm apenas assinaturas de métodos) são simplesmente mais fáceis de usar. classifique e leia.

Dito isto, tendo a ser discreto ao decidir se devo ou não usar uma interface em uma classe.Às vezes eu quero implementações de métodos padrão ou variáveis ​​que serão comuns a todas as subclasses.

É claro que a questão da implementação de múltiplas interfaces também é válida.Se você tiver uma classe que implementa múltiplas interfaces, poderá usar um objeto dessa classe como tipos diferentes no mesmo aplicativo.

O fato de sua pergunta ser sobre PHP torna as coisas um pouco mais interessantes.Digitar em interfaces ainda não é extremamente necessário em PHP, onde você pode alimentar qualquer método com praticamente qualquer coisa, independentemente do seu tipo.Você pode digitar parâmetros de método estaticamente, mas alguns deles estão quebrados (String, acredito, causa alguns soluços).Junte isso ao fato de que você não pode digitar a maioria das outras referências e não há muito valor em tentar forçar a digitação estática em PHP (neste ponto).E por causa disso, o valor das interfaces em PHP, neste ponto é muito menor do que em linguagens com tipagem mais forte.Eles têm o benefício da legibilidade, mas pouco mais.A implementação múltipla nem é benéfica, porque você ainda precisa declarar os métodos e fornecer-lhes corpos dentro do implementador.

As interfaces são como seus genes.

As aulas abstratas são como seus pais reais.

Seus propósitos são hereditários, mas no caso de classes abstratas versus interfaces, o que é herdado é mais específico.

Abaixo estão os pontos para Interface PHP

  1. Ele é usado para definir o número de métodos necessários na classe [se você deseja carregar html, então id e nome são necessários, portanto, neste caso, a interface inclui setID e setName].
  2. A interface força estritamente a classe a incluir todos os métodos definidos nela.
  3. Você só pode definir o método na interface com acessibilidade pública.
  4. Você também pode estender a interface como classe.Você pode estender a interface em php usando a palavra-chave extends.
  5. Estenda múltiplas interfaces.
  6. Você não pode implementar 2 interfaces se ambas compartilharem funções com o mesmo nome.Isso gerará um erro.

Código de exemplo:

interface test{
    public function A($i);
    public function B($j = 20);
}

class xyz implements test{
    public function A($a){
        echo "CLASS A Value is ".$a;
    }
    public function B($b){
        echo "CLASS B Value is ".$b;
    }
}
$x = new xyz();
echo $x->A(11);
echo "<br/>";
echo $x->B(10);

Vimos que as classes e interfaces abstratas são semelhantes no sentido de que fornecem métodos abstratos que devem ser implementados nas classes filhas.No entanto, eles ainda apresentam as seguintes diferenças:

1.As interfaces podem incluir métodos e constantes abstratos, mas não podem conter métodos e variáveis ​​concretos.

2.Todos os métodos da interface devem estar no público escopo de visibilidade.

3. Uma classe pode implementar mais de uma interface, enquanto pode herdar de apenas uma classe abstrata.

                                  interface                      abstract class
the code                     - abstract methods               - abstract methods
                             - constants                      - constants                  
                                                              - concrete methods
                                                              - concrete variables

access modifiers             
                             - public                         - public
                                                              - protected
                                                              - private
                                                                etc.
number of parents          The same class can implement
                           more than 1 interface              The child class can 
                                                              inherit only from 1 abstract class

Espero que isso ajude alguém a entender!

Não sei em outras linguagens, qual é o conceito de interface aí.Mas para PHP, tentarei o meu melhor para explicá-lo.Apenas seja paciente e comente se isso ajudou.

Uma interface funciona como um “contrato”, especificando o que um conjunto de subclasses faz, mas não como o fazem.

A regra

  1. Uma interface não pode ser instanciada.

  2. Você não pode implementar nenhum método em uma interface, ou seja,contém apenas .signature do método, mas não detalhes (corpo).

  3. As interfaces podem conter métodos e/ou constantes, mas nenhum atributo.As constantes de interface têm as mesmas restrições que as constantes de classe.Os métodos de interface são implicitamente abstratos.

  4. As interfaces não devem declarar construtores ou destruidores, pois esses são detalhes da implementação no nível da classe.
  5. Todos os métodos em uma interface devem ter visibilidade pública.

Agora vamos dar um exemplo.Suponha que temos dois brinquedos:um é um cachorro e o outro é um gato.

Como sabemos, um cachorro late e um gato mia. Esses dois têm o mesmo método de fala, mas com funcionalidades ou implementações diferentes.Suponha que estejamos dando ao usuário um controle remoto que possui um botão para falar.

Quando o usuário pressiona o botão de falar, o brinquedo tem que falar, não importa se é um Cachorro ou um Gato.

Este é um bom caso para usar uma interface, não uma classe abstrata porque as implementações são diferentes.Por que?Lembrar

Se você precisar dar suporte às classes filhas adicionando algum método não abstrato, você deve usar classes abstratas.Caso contrário, as interfaces seriam sua escolha.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top