## Interfaces de objetos

Las interfaces de objetos permiten crear código con el cual especificar qué métodos deben ser implementados por una clase, sin tener que definir cómo estos métodos son manipulados.

Las interfaces se definen de la misma manera que una clase, aunque reemplazando la palabra reservada `class` por la palabra reservada `interface` y sin que ninguno de sus métodos tenga su contenido definido.

Todos los métodos declarados en una interfaz deben ser públicos, ya que ésta es la naturaleza de una interfaz.

### `implements`

Para implementar una interfaz, se utiliza el operador `implements`. Todos los métodos en una interfaz deben ser implementados dentro de la clase; el no cumplir con esta regla resultará en un error fatal. Las clases pueden implementar más de una interfaz si se deseara, separándolas cada una por una coma.

> Nota:

> Antes de PHP 5.3.9, una clase no puede implementar dos interfaces que especifiquen un método con el mismo nombre, ya que podría causar ambigüedad. Las versiones más recientes de PHP permiten esto siempre y cuando los métodos duplicados tengan la misma firma.

> Nota:

> Las interfaces se pueden extender al igual que las clases utilizando el operador extends.

> Nota:

> La clase que implemente una interfaz debe utilizar exactamente las mismas estructuras de métodos que fueron definidos en la interfaz. De no cumplir con esta regla, se generará un error fatal.

### `Constantes`

Es posible tener constantes dentro de las interfaces. Las constantes de interfaces funcionan como las constantes de clases excepto porque no pueden ser sobrescritas por una clase/interfaz que las herede.

### Ejemplos

Ejemplo #1 Ejemplo de interfaz

`<?php
// Declarar la interfaz 'iTemplate'
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// Implementar la interfaz
// Ésto funcionará
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
// Ésto no funcionará
// Error fatal: La Clase BadTemplate contiene un método abstracto
// y por lo tanto debe declararse como abstracta (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}
?>`

Ejemplo #2 Interfaces extensibles

`<?php
interface a
{
public function foo();
}
interface b extends a
{
public function baz(Baz $baz);
}
// Ésto sí funcionará
class c implements b
{
public function foo()
{
}
public function baz(Baz $baz)
{
}
}
// Ésto no funcionará y resultará en un error fatal
class d implements b
{
public function foo()
{
}
public function baz(Foo $foo)
{
}
}
?>`

Ejemplo #3 Herencia múltiple de interfaces

`<?php
interface a
{
public function foo();
}
interface b
{
public function bar();
}
interface c extends a, b
{
public function baz();
}
class d implements c
{
public function foo()
{
}
public function bar()
{
}
public function baz()
{
}
}
?>`

Ejemplo #4 Interfaces con constantes

`<?php
interface a
{
const b = 'Interface constant';
}
// Imprime: Interface constant
echo a::b;
// Sin embargo ésto no funcionará ya que no está permitido
// sobrescribir constantes
class b implements a
{
const b = 'Class constant';
}
?>`

Una interfaz, junto con la determinación de tipos, proveen una buena forma de asegurarse que determinado objeto contiene métodos particulares. Vea el operador instanceof y la declaración de tipos.