PHP 8.4.0 RC4 available for testing

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.

add a note

User Contributed Notes 4 notes

up
29
thanhn2001 at gmail dot com
13 years ago
PHP prevents interface a contant to be overridden by a class/interface that DIRECTLY inherits it. However, further inheritance allows it. That means that interface constants are not final as mentioned in a previous comment. Is this a bug or a feature?

<?php

interface a
{
const
b = 'Interface constant';
}

// Prints: Interface constant
echo a::b;

class
b implements a
{
}

// This works!!!
class c extends b
{
const
b = 'Class constant';
}

echo
c::b;
?>
up
20
vcnbianchi
2 years ago
Just as all interface methods are public, all interface methods are abstract as well.
up
6
williebegoode at att dot net
10 years ago
In their book on Design Patterns, Erich Gamma and his associates (AKA: "The Gang of Four") use the term "interface" and "abstract class" interchangeably. In working with PHP and design patterns, the interface, while clearly a "contract" of what to include in an implementation is also a helpful guide for both re-use and making changes. As long as the implemented changes follow the interface (whether it is an interface or abstract class with abstract methods), large complex programs can be safely updated without having to re-code an entire program or module.

In PHP coding with object interfaces (as a keyword) and "interfaces" in the more general context of use that includes both object interfaces and abstract classes, the purpose of "loose binding" (loosely bound objects) for ease of change and re-use is a helpful way to think about both uses of the term "interface." The focus shifts from "contractual" to "loose binding" for the purpose of cooperative development and re-use.
up
-1
xedin dot unknown at gmail dot com
3 years ago
This page says that if extending multiple interfaces with the same methods, the signature must be compatible. But this is not all there is to it: the order of `extends` matters. This is a known issue, and while it is disputable whether or not it is a bug, one should be aware of it, and code interfaces with this in mind.

https://bugs.php.net/bug.php?id=67270
https://bugs.php.net/bug.php?id=76361
https://bugs.php.net/bug.php?id=80785
To Top