Back-End

25 fev, 2016

Usando interfaces de objetos em PHP

100 visualizações
Publicidade

Este artigo pressupõe que você tenha um conhecimento de trabalho de herança de classe, visibilidade e instanciação. Você pode rever esses conceitos no meu artigo anterior sobre esse tema. Você também precisa ter um conhecimento de abstração de classe, e pode rever isso no meu artigo anterior.

Por favor, note que exemplos neste artigo não são modelos completos e são fornecidos para ilustrar um conceito.

Breve análise de abstratos

Antes de começarmos com interfaces, uma breve revisão de abstratos nos ajudará a compreender esses conceitos. Uma classe abstrata pode fornecer métodos abstratos e comuns.

Os métodos abstratos fornecem o método de assinatura (nome da função e parâmetros) que uma classe concreta que se estende deve usar quando implementada. Entenda essa parte da abstração e você irá bem em seu caminho para entender interfaces.

Os métodos comuns, que são totalmente implementados em uma classe abstrata, podem ser usados por uma classe concreta por meio de herança. Esse é o princípio básico de Traits, que é uma nova característica da linguagem PHP.

Interface básica

No PHP, as interfaces são nada mais do que um modelo de assinaturas de método para outras interfaces ou classes concretas implementarem. Uma interface é implementada usando o operador de implementos. Quão simples é isso?

interface oopTemplate {
 
 public function methodOne( $userName );
 public function methodTwo( $userName, $password );
 
}

class oopClass implements oopTemplate {
 
 public function methodOne( $userName ) {
  
  echo 'The user name is '. $userName. '<br>';
  
 }
 
 public function methodTwo( $userName, $password ) {
  
  echo 'The user name is '. $userName. '<br>';
  echo 'The password is '. $password. '<br>';
  
 }
 
}

No exemplo acima, temos uma interface chamada oopTemplate, que contém duas assinaturas de método e uma classe chamada oopClass que implementa a interface aplicando integralmente os métodos necessários. É importante notar que todas as assinaturas de método em uma interface são públicas.

Implementando várias interfaces

Nós também podemos implementar mais de uma interface, separando-as com uma vírgula depois do operador de implementos.

interface oopTemplate {
 
 public function methodOne( $userName );
 public function methodTwo( $userName, $password );
 
}

interface anotherTemplate {
 
 public function methodOne( $userName );
 public function methodThree( $userName, $password );
 
}

class oopClass implements oopTemplate, anotherTemplate {
 
 public function methodOne( $userName ) {
  
  echo 'The user name is '.$userName.'<br>';
  
 }
 
 public function methodTwo( $userName, $password ) {
  
  echo 'The user name is '.$userName.'<br>';
  echo 'The password is '.$password.'<br>';
  
 }
 
 public function methodThree( $userName, $password ){
  
  if( $userName == $password ) {
   return true;
  } else {
   return false;
  }
  
 }
 
}

Como podemos ver, a classe agora implementa tanto o oopTemplate e o anotherTemplate, e aplicou integralmente os métodos necessários em ambas as interfaces.

Observe que a interface anotherTemplate também tem uma assinatura de método chamada methodOne, assim como a interface oopTemplate.

Em versões mais recentes do PHP, desde a versão 5.3.9, isso é permitido, desde que as assinaturas de método sejam as mesmas. Se as assinaturas de método não são as mesmas, ou em versões anteriores do PHP, o método de assinaturas duplicadas criam ambiguidade e o script vai falhar com um erro fatal.

Interface de dependência

Uma interface também pode estender uma outra interface, o que nos permite definir dependências.

interface oopTemplate {
 
 public function methodOne( $userName );
 public function methodTwo( $userName, $password );
 
}

interface anotherTemplate extends oopTemplate {
 
 public function methodOne( $userName );
 public function methodThree( $userName, $password );
 
}

class oopClass implements anotherTemplate {
 
 public function methodOne( $userName ) {
  
  echo 'The user name is '.$userName.'<br>';
  
 }
 
 public function methodTwo( $userName, $password ) {
  
  echo 'The user name is '. $userName. '<br>';
  echo 'The password is '. $password. '<br>';
  
 }
 
 public function methodThree( $userName, $password ){
  
  if( $userName == $password ){
   return true;
  }else{
   return false;
  }
  
 }
 
}

O exemplo acima é quase idêntico ao anterior, mas nós agora usamos a interface anotherTemplate para ser dependente na interface oopTemplate, estendendo-a. A oopClass agora só implementa a interface anotherTemplate, mas ainda deve executar integralmente todos os métodos como antes.

Constantes e interfaces

Enquanto não somos capazes de definir propriedades de classe nas interfaces, podemos definir constantes.

interface oopTemplate {
 
 const memberConstant = 'password';
 
 public function methodOne( $userName );
 public function methodTwo( $userName, $password );
 
}

interface anotherTemplate extends oopTemplate {
 
 public function methodOne( $userName );
 public function methodThree( $userName, $password );
 
}

class oopClass implements anotherTemplate {
 
 public function methodOne( $userName ) {
  
  echo 'The user name is '. $userName. '<br>';
  
 }
 
 public function methodTwo( $userName, $password) {
  
  echo 'The user name is '. $userName. '<br>';
  echo 'The password is '. $password. '<br>';
  
 }
 
 public function methodThree( $userName, $password ) {
  
  if( $password == self::memberConstant ) {
   return true;
  }
  if( $userName == $password ){
   return true;
  } else {
   return false;
  }
  
 }
 
}

A interface oopTemplate define uma constante chamada memberConstant com um valor de ‘password’. A oopClass agora usa essa constante para executar uma verificação lógica para determinar se a propriedade $password é a mesma que o valor da constante.

Uma constante de interface só pode ser definida uma vez, para que outras interfaces ou classes que as herdam não possam alterá-las ou substituí-las.

Conclusão

A maioria dos projetos de desenvolvimento está intimamente relacionada e usa classes abstratas para fornecer implementações parciais junto com assinaturas de método.

Se tudo o que você deseja fornecer é um modelo de assinaturas de métodos, com ou sem dependência, a uma ampla gama de classes, então as interfaces de objeto são o caminho a seguir.

Se você gostou deste artigo, ou tem dúvidas sobre interfaces de objetos do PHP, deixe um comentário aqui.

***

Dave Smith faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://www.phpclasses.org/blog/post/300-Using-PHP-Object-Interfaces.html