Ver Mensaje Individual
  #7 (permalink)  
Antiguo 07/02/2009, 11:16
Avatar de enriqueplace
enriqueplace
 
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: Interface, implements

Estimado Acoevil:

¿Estás intentando leer algún material conceptual del tema o vas a seguir intentando a prueba y error descubrir el concepto de las interfaces y el polimorfismo?

Como comentaba anteriormente, es un "contrato de implementación" y ese es el centro del asunto. Si tu haces una clase "Impresora" (que ofrece el servicio de imprimir cualquier cosa que recibe), deberá poder recibir objetos que tenga la capacidad de poder decirle a la impresora "qué imprimir".

Código PHP:

class Impresora
{
   public function 
imprimir($objetoImprimible)
   {
      echo 
$objetoImprimible->getContenidoImprimible();
   }
}

class 
Hola
{
   public function 
getContenidoImprimible()
   {
      return 
"soy una hoja";
   }
}
// Funciona
Impresora::imprimir(new Hoja());

class 
Informe extends Hoja
{
}

// Funciona
Impresora::imprimir(new Curriculum());

class 
Libro
{
}

// No funciona!
Impresora::imprimir(new Libro()); 
Funciona? Depende de cómo esté implementado la Impresora, aquí usa polimorfismo, el tema es ... qué método va a ejecutar de cada objeto que recibe? cómo queda consistente al diseño? cómo aseguro que las clases lo cumplan?

Lo que hicimos anteriormente lo llamo "polimorfismo débil" o "de palabra", ya que el diseño es débil y no asegura que la clase Impresora no se rompa ante una clase que no cumple con el "contrato de palabra" de tener el método para entregar el contenido imprimible.

Puedes hacer "polimorfismo por herencia" y hacer que el diseño sea más robusto

Código PHP:
class Impresora
{
   public function 
imprimir(Hoja $objetoImprimible)
   {
      echo 
$objetoImprimible->getContenidoImprimible();
   }

Aquí aseguramos que la impresora solo acepte elementos de tipo Hoja, por lo tanto el informe es también de tipo hoja y como hoja tiene el método obtener contenido, este diseño es más consistente que el primero (todo objeto que quiera pasar que no sea de tipo Hoja será rechazado y la clase no intenta imprimir algo que no se puede).

Ahora el punto es, qué hacemos con el libro? Sí tiene hojas, pero no es un tipo de hoja, tampoco vamos a crear una impresora por cada tipo de elemento que queremos imprimir (impresora de hojas e impresora de libros).

Bien, aquí es donde se necesitan las interfaces. Creas una interfaz Imprimible que tiene solo la firma del método getContendioImprimible y defines que la Impresora solo acepta objetos "imprimibles".

Lo que sucede es lo siguiente:
  1. Si modificas la clase para que valide la interfaz, cualquier objeto que quiera pasar por el método este le dirá que tiene que cumplir la interfaz Imprimible
  2. Cuando a la clase le agregas "implements Imprimible", automáticamente el sistema que dirá que te falta la implementación del método getContenidoImprimible
  3. Una vez que lo implementes, recién ahí podrás acceder al método "imprimir".
A eso se le llama "contrato de implementación", necesitas "firmar" un contrato para poder obtener un "servicio", lo cual esto asegura una serie de condiciones para poder usarlo.

¿Qué pasa si el método lo implementas vacío? Ese no es problema de la interfaz, es de la clase que no hizo lo que debía, cada objeto tiene la responsabilidad de proveer el contenido correspondiente (es más, todavía puedes validar que la impresora retorne una excepción si el método "contenido" retorna vacío) y cada objeto diferirá del otro cómo implementará su parte.


PD: te lo digo con el mayor de los respetos, sal de la ignorancia, no seas necio y buscan un libro o un tutorial que hable de los conceptos de la POO y toque el tema de interfaces, más allá de la sintaxis.

"Un millón de monos golpeando un teclado no generarán un sistema funcional", lo que significa que sin el conocimiento base suficiente no lo vas a lograr.
__________________
Blog phpsenior.com Cursos a Distancia surforce.com