No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Polimorfismo: interfaz

11/19
Recursos

Aportes 54

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Esto es algo que hab铆a comentado en una clase anterior, una interfaz se puede usar para crear diferentes m茅todos que se comporten de maneras distintas, pero esta sirve como plantilla, y sin querer queriendo ya estamos trabajando usando polimorfismo.

Realmente estas palabras tan 鈥渇ancys鈥 y 鈥減rofesionales鈥 son simplemente nombres que le ponemos a las cosas para saber c贸mo identificarlas, pero al final su definici贸n e implementaci贸n es super sencilla, solo hay que quitarse el miedo que estas palabras nos generan

Adjunto mi c贸digo ya separado de la clase anterior:

Admin.php

<?php

require_once("Base.php");

class Admin extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Base.php

<?php

abstract class Base
{
    protected $name;

    private function getClassName ()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }

}

Guest.php

<?php

require_once("Base.php");

class Guest extends Base 
{
    protected $name = 'Invitado';
}

Index.php

<?php

require_once("Base.php");
require_once("Admin.php");
require_once("User.php");
require_once("Guest.php");

$guest = new Guest();
echo $guest->login();
echo ('<br>');
//Mi nombre es Invitado de la clase guest.


$user = new User('Iridian');
echo $user->login();
echo ('<br>');
//Mi nombre es Iridian de la clase user.


$admin = new Admin('Guadalupe');
echo $admin->login();
echo ('<br>');
//Mi nombre es Guadalupe de la clase Admin.


User.php

<?php

require_once("Base.php");

class User extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
    }


}

Polimorfismo: interfaz


En programaci贸n avanzada siempre vamos a trabajar sobre interfaces. Vamos a trabajar con estas porque es lo que enviamos, o sea, que lo enviamos a nivel de configuraci贸n.

Nos vamos a encargar de preparar todo el c贸digo necesario, as铆 no trabajamos sobre _usuarios _sino sobre la interfaz de usuarios.

  • index.php
<?php

require_once "./user.php";
require_once "./post.php";

$user = new User();
echo $user->all();

$post = new Post();
echo $post->all();
  • search_interface.php
<?php

interface Search {
    public function all();
}
  • user.php
<?php

require_once "./search_interface.php";

class User implements Search {
    public function all() {
        return "Obteniendo a los Usuarios";
    }
}
  • post.php
<?php

require_once "./search_interface.php";

class Post implements Search {
    public function all() {
        return "Obteniendo a los Post";
    }
}

Por si alguien se pregunta cual es la diferencia entre 鈥渆xtends鈥 e 鈥渋mplements鈥, es esta (cualquier correcci贸n es bienvenida):

Extends: Se utiliza cuando trabajamos con clases y permite extender (heredar) las propiedades y el comportamiento de una clase existente (padre) a una subclase (hija).

Implements: Se utiliza al trabajar con interfaces y permite (y se debe) implementar todos los m茅todos definidos en la interfaz, dentro de la clase donde se esta implementando

En una interfaz, todos los m茅todos son abstractos. Osea, el c贸digo de cada m茅todo se define en la clase que implementa la interfaz.

Ya con esta clase quedo mucho m谩s claro como es que funcionan las interfaces ya que cuando las vimos de forma muy r谩pida hace unas clases la verdad me quede con la idea principal pero no entend铆a la implementaci贸n de estas鈥

Comparto mi c贸digo con el resultado comentado.
.
BaseInterface

<?php

// Creando la interfaz 'BaseInterface'
interface BaseInterface{

  // Creando m茅todo necesario para las clases que implementen est谩 interfaz
  public function all();

}

?>

.
User

<?php

// Incluyendo el archivo de 'BaseInterface'
include_once("BaseInterface.php");

// Creando clase que implementa la Interfaz 'BaseInterface'
class User implements BaseInterface{

  /*
    Como la interfaz de la cual se implementa esta clase tiene 1 m茅todo,
    se debe cumplir el contrato e implementar dicho m茅todo en esta clase si no arroja el siguiente error: 
    Fatal error: Class User contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (BaseInterface::all)
  */

  // Implementando el m茅todo de la interfaz
  public function all(){
    return 'Obteniendo a todos los Usuarios';
  }

} 

// Instanciando un objeto de la clase 'User'
$user1 = new User();
echo $user1->all(); // Obteniendo a todos los Usuarios

?>

.
Post

<?php

// Incluyendo el archivo de 'BaseInterface'
include_once("BaseInterface.php");

// Creando la clase 'Post' que implementa la interface 'BaseInterface'
class Post implements BaseInterface{

  // Creando el m茅todo necesario que se declaro en la Interfaz
  public function all(){
    return "Obteniendo todos los POST";
  }

}

// Instanciando un objeto de la clase 'Post'
$post1 = new Post();
echo $post1->all(); // Obteniendo todos los POST

?>

Adjunto mi c贸digo que vimos en la clase acerca de la interfaz:

index.php

<?php

require_once("SearchInterface.php");
require_once("User.php");
require_once("Post.php");


$user = new User();
echo $user->all();


$post = new Post();
echo $post->all();

Post.php

<?php

require_once("SearchInterface.php");

class Post implements Search
{
    //aqu铆 desarrollamos
    public function all()
    {
        return "Obteniendo a los Users aunque tambi茅n puedo obtener un xml <br/>";
    }
}

SearchInterface.php

<?php


interface Search
{
    //declaramos un unico m茅todo para que funcione para el resto
    public function all();

}

User.php

<?php

require_once("SearchInterface.php");

class User implements Search
{
    //aqu铆 desarrollamos
    public function all()
    {
        return "Obteniendo a los Users aunque tambi茅n puedo obtener un json <br/>";
    }
}

Comparto mi codgio

Base.php

<?php

abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }
}

Guest.php

<?php

class Guest extends Base
{
    protected $name = 'Invitado';
}

User.php

<?php

class User extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Admin.php

<?php

class Admin extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

index.php

  • En este caso como estamos modularizando todos los archivos al mismo index no se debe llamar en cada documento por separado, simplemente se llama primero que toso los demas documentos ya que estos depende de 鈥淏ase.php鈥.
<?php

require_once "Base.php";
require_once "Guest.php";
require_once "User.php";
require_once "Admin.php";



$guest = new Guest;
echo $guest->login();
echo ("<\n>");


$user = new User('Reagan');
echo $user->login();
echo ("<\n>");


$admin = new Admin('Zeus');
echo $admin ->login();
echo ("<\n>");

Polimorfismo made easy

Implementacion para reutilizar codigo que pueda cambiar de formas.

  • Podemos obtener este comportamiento a travez de interfaces que se declaran como una configuracion general.
  • O tambien desde una clase abstracta dependiendo de los casos.

Ejemplos en la clase: Polimorfismo - Interfaz

<code> 
y este es el archivo Guest.php
<?php

class Guest extends Base
{
    protected $name = 'Invitado';
}
<code> 
<?php
//este es el archivo index.php de la practica que dice el profe al inicio de la clase
include './Base.php';
include './Admin.php';
include './Guest.php';
include './User.php';

$gues = new Guest();
echo $gues->login();

$user = new User("D4ni3lH4ck");
echo $user->login();

$admin = new Admin("Jaidy");
echo $admin->login();

Base.php

<?php

abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }
}

Admin.php

<?php

class Admin extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

User.php

<?php

class User extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Guest.php

<?php

class Guest extends Base
{
    protected $name = 'Invitado';
} 

Index.php

<?php

require_once ('./Base.php');
include './Admin.php';
include './User.php';
include './Guest.php';

$guest = new Guest();
echo $guest->login();
echo "<br>";
$user = new User('Johann');
echo $user->login();
echo "<br>";
$admin = new Admin('Lynda');
echo $admin->login();

index.php

<?php

require_once 'Guest.php';
require_once 'User.php';
require_once 'Admin.php';

$guest = new Guest();
echo $guest->login();

$user = new User('Italo');
echo $user->login();

$admin = new Admin('Lynda');
echo $admin->login();

Base.php


<?php

abstract class Base 
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login() 
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }
}

Guest.php

<?php

require_once 'Base.php';

class Guest extends Base 
{
    protected $name = 'Invitado';
}

User.php

<?php

require_once 'Base.php';

class User extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Admin.php

<?php

require_once 'Base.php';

class Admin extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Aprendi a usar Polimorfismo y a implentar Interfaces cuando desarrolle mi primera Clean Architecure, aplicando (Interface) = 鈥業Resository鈥, luego la implementacion 鈥楻epository鈥 asi puedo cambiar la implementacion sin tener que cambiar la Interface, asi no rompo nada, etc etc

require_once('./User.php');
require_once('./Post.php');

$user = new User();
echo $user->all();

$user = new Post();
echo $user->all();
<?php

require('./Guest.php');
require('./User.php');
require('./Admin.php');

$guest = new Guest();
echo $guest->login();

$user = new User('Miguel');
echo $user->login();

$admin = new Admin('Sublime');
echo $admin->login();

No trabajamos sobre Usuarios directamente
pero sobre la interfaz de Usuarios
.

Completamente claro.

El polimorfismo es exactamente que una cosa tenga diferentes comportamientos, esto es una capacidad o virtud; tienes un 煤nico elemento que se comporta de diferentes maneras y adem谩s podr铆a de acuerdo a su configuraci贸n arrojar diferentes resultados.
En programaci贸n avanzada siempre vamos a trabajar con interfaces, nosotros programamos en base de interfaces porque es lo que enviamos, me refiero a que se env铆a a nivel de configuraci贸n.
POLIMORFISMO : una 煤nica cosa se comporta de diferentes formas o emite diferentes resultados.

Resumen de la clase

<?php

interface Search{

    public function all();
}

class User implements Search{
    public function all(){
        return 'All users';
    }
}

class Post implements Search{
    public function all(){
        return 'All posts';
    }
}

$user = new User();
echo $user->all();

$post = new Post();
echo $post->all();

Ejemplo de polimorfismo

Est谩 genial eso de correr los archivos de esta manera, se hace m谩s entendible que ver tanto c贸digo en un solo archivo. Comparto el ejercicio de la clase.

index.php

require_once 鈥./Base.php鈥;
require_once 鈥./Admin.php鈥;
require_once 鈥./User.php鈥;
require_once 鈥./Guest.php鈥;

$guest = new Guest();
echo $guest->login();

$user= new User(鈥楳arlon鈥);
echo $user->login();

$admin = new Admin(鈥楢ndres鈥);
echo $admin->login();

Admin.php

class Admin extends Base
{
public function __construct($name)
{
$this->name = $name;
}
}

User.php

class User extends Base
{
public function __construct($name)
{
$this->name = $name;
}
}

Guest.php

class Guest extends Base
{
protected $name = 鈥業nvitado鈥;
}

Base.php

abstract class Base
{
protected $name;

private function getClassName()
{
    return get_called_class();
}

public function login()
{
    return"<p>Mi nombre es $this->name desde la clase {$this->getClassName()} <br><p>";
}

}

Buenas! Comparto las clases en sus correspondientes archivos.


.
index

<?php

include "Base.php";
include "Admin.php";
include "User.php";
include "Guest.php";



$guest = new Guest();
echo $guest-> login();


$user = new User("Nicol谩s");
echo $user-> login();

$admin = new Admin("Pedro");
echo $admin-> login();

Base

<?php
abstract class Base
{
    protected $name;
    private  function getClassName()
    {
        return get_called_class();
    }
    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }

}

Admin

<?php
require_once("Base");

class Admin extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
        
    }
}

User

<?php
require_once("Base");


class User extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
        
    }
}

Guest

<?php

class Guest extends Base 
{
    protected $name = "invitado";
}

Clases abstractas
Una clase se define como abstracta cuando representa una entidad que no deber铆a ser instanciada.

En los ejemplos utilizados hasta ahora se define una clase Vehiculo, que sirve de base para las clases Coche, Moto, etc鈥 Sin embargo, en el mundo real (dominio del problema) no se encuentran objetos de la clase Vehiculo, sino que existen coches, motos, camiones鈥 Al final todos son veh铆culos, pero todos son de un tipo m谩s concreto (veh铆culo es un t茅rmino abstracto que agrupa a una serie de sistemas que se utilizan para el transporte).

Por lo tanto ser铆a bastante l贸gico declarar la clase Vehiculo como abstracta, forzando as铆 la necesidad de construir clases derivadas que representen elementos m谩s concretos:

abstract class Vehiculo
{
  public $potencia;
  public $peso;
}

//// ERROR: no se puede instanciar una clase abstracta
//// $objVehiculo = new Vehiculo();


//// una Moto es un Vehiculo
class Moto extends Vehiculo
{
  public $anguloMaxInclinacionEnCurva;
}

//// creamos un objeto Moto
$obj_moto = new Moto();

Las clases abstractas se suelen utilizar como base para crear una jerarqu铆a en la que todas las clases comparten una parte de la interfaz. Dentro de una clase abstracta se pueden definir m茅todos abstractos. Los m茅todos abstractos no tienen implementaci贸n (ni funcionalidad), simplemente definen una parte de la interfaz que deben implementar las clases derivadas (la clase base obliga a que se definan esos m茅todos en la clase derivada).

Por ejemplo, para la clase Vehiculo se podr铆a definir un m茅todo abstracto aceleracionAproximada() de forma que tenga que ser implementado para cada tipo de veh铆culo (la aceleraci贸n depende de la masa (peso), de la potencia y de otros factores que dependen a su vez del tipo de veh铆culo):

abstract class Vehiculo
{
  public $potencia;
  public $peso;

  function __construct($potencia,$peso)
  {
    $this->potencia = $potencia;
    $this->peso = $peso;

    return true;

  }

  function relacionPesoPotencia()
  {
    if ($this->potencia>0)
    {
      return ($this->peso/$this->potencia);
    }

    return -1;
  }

  //// devuelve el tiempo en alcanzar los 100 Km/h
  //// partiendo de cero
  //// cada tipo de vehiculo tendra una
  //// aceleracion aproximada en funcion de sus
  //// caracteristicas particulares
  abstract function aceleracionAproximada();

}

//// una Moto es un Vehiculo
class Moto extends Vehiculo
{

  function __construct($potencia,$peso)
  {
    $this->potencia = $potencia;
    $this->peso = $peso;

    return true;
  }

  //// devuelve el tiempo en alcanzar los 100 Km/h
  //// partiendo de cero
  function aceleracionAproximada()
  {
     $coeficienteTransmision = 3.0;

     $t = $this->peso * 771.73 / (2.0 * $this->potencia * 735);
     $t = $t * $coeficienteTransmision;
     return $t;
  }
}


//// un Coche es un Vehiculo
class Coche extends Vehiculo
{
  function __construct($potencia,$peso)
  {
    $this->potencia = $potencia;
    $this->peso = $peso;

    return true;
  }

  //// devuelve el tiempo en alcanzar los 100 Km/h
  //// partiendo de cero
  function aceleracionAproximada()
  {
     $coeficienteTransmision = 2.2;

     if ($this->potencia==0)
     {
       return -1;
     }

     $t = $this->peso * 771.73 / (2 * $this->potencia * 735);
     $t = $t * $coeficienteTransmision;

     return $t;
  }
}

//// un coche (125CV, 1300Kg)
$coche = new Coche (125, 1300);
echo "coche (0-100): ".$coche->aceleracionAproximada();
echo "<br>";

//// una moto (60CV, 250Kg)
$moto = new Moto (60, 250);
echo "moto (0-100): ".$moto->aceleracionAproximada();
echo "<br>";

Una clase derivada de una clase abstracta puede ser abstracta a su vez. El objetivo es el mismo: servir de base com煤n para otras clases m谩s espec铆ficas y obligar a sus clases derivadas a que implementen una determinada funcionalidad.

Una clase derivada puede omitir la declaraci贸n de un m茅todo abstracto de su clase base, pero s贸lo si se declara como abstracta. En este caso, la implementaci贸n del m茅todo ser谩 responsabilidad de las clases derivadas a partir de este nivel jer谩rquico.

/```
/// un Coche es un Vehiculo
//// se declara como abstracta para no tener que
//// implementar aceleracionAproximada()
abstract class Coche extends Vehiculo
{
  function __construct($potencia,$peso)
  {
    $this->potencia = $potencia;
    $this->peso = $peso;

    return true;
  }
}

//// un Formula1 es un Coche
class Formula1 extends Coche
{
  function __construct($potencia,$peso)
  {
    $this->potencia = $potencia;
    $this->peso = $peso;

    return true;
  }

  //// devuelve el tiempo en alcanzar los 100 Km/h
  //// partiendo de cero
  function aceleracionAproximada()
  {
     $coeficienteTransmision = 3.5;

     if ($this->potencia==0)
     {
       return -1;
     }

     $t = $this->peso * 771.73 / (2 * $this->potencia * 735);
     $t = $t * $coeficienteTransmision;

     return $t;
  }
}


//// ERROR: Coche es ahora una clase abstracta
//// un coche (125CV, 1300Kg)
//// $coche = new Coche (125, 1300);
//// echo "coche (0-100): ".$coche->aceleracionAproximada();
//// echo "<br>";

//// un formula 1 (900CV, 600Kg)
$ferrari = new Formula1 (900, 600);
echo "ferrari (0-100): ".$ferrari->aceleracionAproximada();
echo "<br>";

Herencia m煤ltiple

PHP no soporta herencia m煤ltiple (una clase derivada s贸lo puede tener una clase base). Sin embargo s铆 es posible que una misma clase implemente varios interfaces.

Interfaces

El concepto de interface es muy similar al de la clase abstracta. Se utiliza para definir una interfaz (conjunto de m茅todos) y forzar a que las clases derivadas implementen la funcionalidad necesaria para dar soporte a ese interfaz:

interface InterfaceVehiculo
{
  public function dimePeso();
  public function dimePotencia();

} ////    fin de la interface "Vehiculo"


class Moto implements InterfaceVehiculo
{
  private $peso;
  private $potencia;

  function __construct($potencia,$peso)
  {
    $this->potencia = $potencia;
    $this->peso = $peso;

    return true;

  } //// fin de "__constructor"

  //// implementa el metodo dimePeso()
  //// declarado en la interfaz
  function dimePeso()
  {
    return $this->peso;
  }

  //// implementa el metodo dimePeso()
  //// declarado en la interfaz
  function dimePotencia()
  {
    return $this->potencia;
  }
}

Si la clase Moto del ejemplo anterior no implementara alguno de los m茅todos del interfaz InterfaceVehiculo aparecer铆a un error.

La diferencia fundamental entre una clase abstracta y un interface es que la clase abstracta puede tener una implementaci贸n, una funcionalidad (como por ejemplo el m茅todo relacionPesoPotencia() de la clase abstracta Vehiculo de un ejemplo anterior), mientras que los interfaces s贸lo son una especie de molde para construir clases con (al menos) un conjunto espec铆fico de m茅todos.

Los interfaces son muy 煤tiles para definir un mecanismo com煤n de comunicaci贸n en objetos de tipolog铆a variada. Por ejemplo:

interface Ficha
{
  public function queEres();
}

//// clase Persona
class Persona implements Ficha
{
  public function queEres()
  {
     return "Soy una persona";
  }
}

//// clase Gato
class Gato implements Ficha
{
  public function queEres()
  {
     return "Soy un gato";
  }
}

//// clase Barco
class Barco implements Ficha
{
  public function queEres()
  {
     return "Soy un barco";
  }
}

En el ejemplo anterior se establece una interfaz com煤n, que puede ser utilizada por otros objetos y funciones para comunicarse con los objetos sin necesidad de saber si son de un tipo concreto:

//// pregunta 'que eres' a todos los objetos
function curiosidad ($arrayObjetos)
{
   foreach ($arrayObjetos as $objeto)
   {
      echo $objeto->queEres();
      echo "<br>";
   }
}


//// creamos objetos de varios tipos
//// (todos tienen en comun el mismo interface)
$arrayObj[] = new Persona();
$arrayObj[] = new Gato();
$arrayObj[] = new Barco();

//// pasamos el array a curiosidad()
curiosidad ($arrayObj);

//// salida:
//// Soy una persona
//// Soy un gato
//// Soy un barco

Como los interfaces son simples plantillas, una clase puede implementar todos los interfaces que sea necesario.

Tambi茅n es posible aplicar a la vez herencia (simple) e implementaci贸n a una clase:

interface Ficha
{
  public function queEres();
}

interface Identificacion
{
  public function quienEres();
}

//// clase Persona
class Persona
{
  public $nombre;
}


//// un Piloto es una Persona
class Piloto extends Persona implements Ficha, Identificacion
{
  public function queEres()
  {
     return "Soy un piloto de carreras";
  }

  public function quienEres()
  {
     return "Mi nombre es: ".$this->nombre;
  }

}

En ocasiones puede ser 煤til aplicar un interface a una clase base abstracta, con el fin de obligar a sus clases derivadas a implementarlo. Al igual que sucede con la herencia de las clases abstractas, una clase puede delegar en sus clases derivadas la implementaci贸n de un interface, pero tiene que ser declarada como abstracta.

interface Ficha
{
  public function queEres();
}

//// clase Persona
//// es abstracta porque no interesa implementar
//// la interfaz de Ficha en este nivel
abstract class Persona implements Ficha
{
  public $nombre;

  abstract function dimeNombre();
}

//// un Piloto es una Persona
class Piloto extends Persona
{

  //// implementa el metodo abstracto de
  //// su clase base
  public function dimeNombre()
  {
     return $this->nombre;
  }

  //// implementa la interfaz impuesta por Ficha
  public function queEres()
  {
     return "Soy un piloto de carreras";
  }

}


$piloto = new Piloto;
$piloto->nombre = "Fernando Alonso";

echo "nombre: ".$piloto->dimeNombre();
echo "<br>";
echo "驴que eres?: ".$piloto->queEres();

Tomado de Modelo de objetos en PHP5 - Felipe Fern谩ndez Perera

<?php

require_once 'Guest.php';
require_once 'User.php';
require_once 'Admin.php';

$guest = new Guest();
echo $guest->login();

$user = new User('Usuario X');
echo $user->login();

$admin = new Admin('Administrador Y');
echo $admin->login();

?>

Comparto mi c贸digo separado

Base.php

<?php

abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }
}

Admin.php

<?php
require_once 'Base.php';

class Admin extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

User.php

<?php
require_once 'Base.php';

class User extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Guest.php

<?php
require_once 'Base.php';

class Guest extends Base
{
    protected $name = 'Invitado';
}

index.php

<?php
require_once 'Guest.php';
require_once 'User.php';
require_once 'Admin.php';

$guest = new Guest();
echo $guest->login();
echo "<br>";

$user = new User('Daniel');
echo $user->login();
echo "<br>";

$admin = new Admin('Stiven');
echo $admin->login();
echo "<br>";
Una interfaz es como un contrato o un compromiso. Cuando una clase implementa una interfaz, se obliga a declarar los metodos y ateibutos que diga esa interfaz, como una especie de Sim贸n Dice. Sin embargo, la interfaz te dice que m茅todos declarar, mas no que debe tener por dentro ese metodo, eso ya depende de cada clase.
  • 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.

Seg煤n entiendo es una forma de asignarle metodos y funciones a las clases pero no se declara la acci贸n, por ejemplo saludoAnimales y no se define que hace, luego defino las clases, perro, gato y vaca por ejemplo y saludoAnimales para perro regresaria 鈥渓adrar鈥 o 鈥済uaf鈥 (no se como representar el sonido XD) luego en la clase gato regresaria 鈥渕aullar鈥 o 鈥渕iaauuu鈥 y en la vaca regresaria 鈥渕ugir鈥 o 鈥渕uuuu鈥 (no recordaba el nombre de eso)

As铆 entend铆 yo

Interfaz

Las interfaz es el recurso ideal para la implementacion del polimorfismo, ya que las interfaz es un conjunto de declaraciones de funciones o metodos sin incluir su codificacion, dejando a la clase que implementa la interfaz esta tarea.

Algunas caracter铆stias propias de interfaz que encontre por ahi.

Todos los metodos definidos en una interfaz, deben ser codificados en la clase que implementa dicha interfaz.
La clase que implemente la interfaz debe utilizar exactamente las mismas estructuras de metodos que fueron definidos en la interfaz.
Las interfaces se pueden extender al igual que las clases mediante el operador extends.
Una clase puede implementar diferente interfaces.
Una interfaz no se puede instanciar y todos sus metodos son publicos dada la propia naturaleza de la interfaz.
Una interfaz no puede contener ni atributos, ni metodos implementados, solo declaraciones de metodos y constantes.

resultado


index

<?php

require_once 'UserService.php';
require_once 'UserServiceImpl.php';
require_once 'UserServiceImpl2.php';

$userService = new UserServiceImpl();

echo "<pre>";
echo $userService->createUser('user') . "<br><br>";
echo $userService->deleteUserById(1) . "<br><br>";

$userService = new UserServiceImpl2();

echo $userService->createUser('user') . "<br><br>";
echo $userService->deleteUserById(1) . "<br><br>";

UserService

<?php

interface UserService
{
    public function createUser($user);
    public function deleteUserById($idUser);
    public function updateUser($user);
    public function getUserById($idUser);
}

UserServiceImpl

<?php

require_once 'UserService.php';

class UserServiceImpl implements UserService
{
    function createUser($user)
    {
        return "the user was been created from {$this->getClassName()}";
    }

    function deleteUserById($idUser)
    {
        return "the user was been removed from {$this->getClassName()}";
    }

    function updateUser($user)
    {
        return "the user was been updated from {$this->getClassName()}";
    }

    function getUserById($idUser)
    {
        return "user {$this->getClassName()}";
    }

    private function getClassName()
    {
        return get_called_class();
    }
}

UserServiceImpl2

<?php

require_once 'UserService.php';

class UserServiceImpl2 implements UserService
{
    function createUser($user)
    {
        return "the user was been created from {$this->getClassName()}";
    }

    function deleteUserById($idUser)
    {
        return "the user was been removed from {$this->getClassName()}";
    }

    function updateUser($user)
    {
        return "the user was been updated from {$this->getClassName()}";
    }

    function getUserById($idUser)
    {
        return "user from {$this->getClassName()}";
    }

    private function getClassName()
    {
        return get_called_class();
    }
}

listo, solo nose si de debe incluir la clase base en cada archivo , lo hice pero usando el require_one por si acaso

<?php 

require_once 'Guest.php';
require_once 'User.php';
require_once 'Admin.php';

$guest = new Guest();
echo $guest->login();

echo '</br>';

$useer = new User('Manuel');
echo $useer->login();

echo '</br>';

$admin = new Admin('Angel');
echo $admin->login();

11. Polimorfismo: Interfaz

Comparto el primer reto realizado, en este caso, al ponerlo en archivos externos tuve que 鈥渞equerirlos鈥 desde el index:

Comparto el c贸digo de la clase tambi茅n:

index.php

<?php

interface Search
{
    public function all();
}

class User implements Search
{
    public function all()
    {
        return "Obteniendo a los Users, XML";
    }
}

class Post implements Search
{
    public function all()
    {
        return "Obteniendo a los Posts, JSON";
    }
}

$user = new User();
echo $user->all();

$post = new Post();
echo $post->all();

馃 Cosas que son sencillas pero al principio era todo una locura tratar de entenderlo

Entend铆 todo el concepto de la siguiente manera:
Una interfaz es como un contrato, que te exige si o si usar los m茅todos que est谩n colocados o definidos en la interfaz.

No es necesario, colocar los par谩metros dentro de los m茅todos que est谩n en la interfaz.
Para que, cuando utilices, en tus clases esos m茅todos obligatorios, puedas colocarle el par谩metro que tu quieras (convirti茅ndose en polim贸rfico)

Polimorfimos usando Interface

Search_Interface.php

<?php

interface Search_Interface
{
    public function all();
}

User.php

<?php

require_once 'Search_Interface.php';

class User implements Search_Interface
{
    public function all()
    {
        return 'Obteniendo a los Users, XML';
    }
}

Post.php

<?php

require_once 'Search_Interface.php';

class Post implements Search_Interface
{
    public function all()
    {
        return "Obteniendo todo los Posts, JSON";
    }
}

Les Comparto mi c贸digo de la clase de anterior:

Base.php

<?php
abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }

}

Admin.php

<?php

require_once 'Base.php';

class Admin extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

User.php

<?php

require_once 'Base.php';

class User extends Base 
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Guest.php

<?php

require_once 'Base.php';

class Guest extends Base
{
    protected $name = 'Invitado';
} 

index.php

<?php

require_once 'Admin.php';
require_once 'User.php';
require_once 'Guest.php';

$guest = new Guest;
echo $guest->login();
echo '<br>';

$user = new User('David');
echo $user->login();
echo '<br>';

$admin = new Admin('Armando Paredes');
echo $admin->login();
echo '<br>';
  1. Polimorfismo (abstract)
  • index.php
<?php
require_once 'Base.php';

class Guest extends Base
{
    protected $name = 'Invitado';
}
  • Admin.php
<?php
require_once 'Base.php';

class Admin extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}
  • Base.php
<?php
abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()} <br />";
    }
}
  • Guest.php
<?php
require_once 'Base.php';

class Guest extends Base
{
    protected $name = 'Invitado';
}
  • User.php
<?php
require_once 'Base.php';

class User extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}
  1. Polimorfismo (interface)
  • index.php
<?php
require_once 'User.php';
require_once 'Post.php';

$user = new User();
echo $user->all();
echo "<br />";

$post = new Post();
echo $post->all();
  • Post.php
<?php
require_once 'Searchinterface.php';

class Post implements Search
{
    public function all()
    {
        return "Obteniendo a los Posts, JSON";
    }
}
  • Searchinterface.php
<?php

interface Search
{
    public function all();
}
  • User.php
<?php
require_once 'Searchinterface.php';

class User implements Search
{
    public function all()
    {
        return "Obteniendo a los Users, XML";
    }
}

M谩s claro, 茅chale agua. Gracias @italomoralesf

Lo m谩s importante de las interfaces es que nos permite definir el est谩ndar de que llevaran nuestros clases y m茅todos, haciendo as铆 nuestro c贸digo mas unificado aun si trabajamos varios personas en el mismo proyecto.

El reto ayuda mucho a repasar

<?php
require('Base.php');
require('Admin.php');
require('User.php');
require('Guest.php');

$guest = new Guest();
echo $guest->login();

$user = new User('Jose');
echo $user->login();


$admin = new Admin('Miguel');
echo $admin->login();

Interfaces everywhere

listo, me funciono.
index.php

require_once('Admin.php');
require_once('User.php');
require_once('Guest.php');

$guest = new Guest();
echo $guest->login()."</br>";

$user = new User('Kenneth');
echo $user->login()."</br>";

$admin = new Admin('Wizard');
echo $admin->login()."</br>";

Admin.php

require_once('AbstractInterface.php');

class Admin extends Base {
	public function __construct($name) {
		$this->name = $name;
	}
}

User.php

require_once('AbstractInterface.php');

class User extends Base {
	public function __construct($name) {
		$this->name = $name;
	}
}

Guest.php

require_once('AbstractInterface.php');

class Guest extends Base {
	protected $name = 'invitado';
}

Me gusto esta frase del profesor:
鈥淓n programaci贸n avanzada, siempre se trabaja con interfaces鈥.

Usen interfaces, son de lo mejor que podemos encontrar en POO y nos permiten hacer mas mantenible y escalable nuestro sistema.

Yo utilizo el polimorfismo de esta manera, con interfaces

la verdad sigo sin entender las clases padres, contructores, alguien me puede ayudar ya que estoy confundido

Mi archivo separado

Index.php

<?php
require_once('Base.php');
require_once('Guest.php');
require_once('Admin.php');
require_once('User.php');
$guest = new Guest();
echo $guest->login() . "<br>";

$user = new User("Usuario");
echo $user->login() . "<br>";

$admin = new Admin("Admin");
echo $admin->login();

Guest.php

<?php
require_once('Base.php');
class Guest extends base
{
    protected $name = 'Invitado';
}

Admin.php

<?php
require_once('Base.php');
class Admin extends base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

User.php

<?php
require_once('Base.php');
class User extends base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}

Base.php

<?php

abstract class Base
{
    protected $name;
    private function getClassName()
    {
        return get_called_class();
    }
    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }
}

Les comparto el resultado de mi pr谩ctica.

index.php

<?php

include 'Guest.php';
include 'User.php';
include 'Admin.php';

$guest = new Guest();
echo $guest->login();

$user = new User('Juan');
echo $user->login();

$admin = new Admin('Valen');
echo $admin->login();

User.php

<?php

require_once 'Base.php';

class User extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}```

Guest.php

<?php

require_once 鈥楤ase.php鈥;

class Guest extends Base
{
protected $name = 鈥業nvitado鈥;
}


Admin.php

<?php

require_once 鈥楤ase.php鈥;

Class Admin extends Base
{
public function __construct($name)
{
$this->name = $name;
}
}


Base.php

<?php

abstract class Base
{
protected $name;

private function getClassName()
{
    return get_called_class();
}

public function login()
{
    return "Mi nombre es $this->name desde la calse {$this->getClassName()}";
}

}




Claro, como la interfaz obliga a toda clase que la extienda implementarla pero no dice estrictamente como, el polimorfismo se puede dar al personalizar la implementaci贸n de la interfaz en cada clase, cambiando por ejemplo los argumentos de alg煤n m茅todo.

Ejercicio realizado
Done!!

Mi c贸digo:

Fichero lib/base.php.

<?php // @alejandro Base.

abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}<br>";
    }
}```

Fichero lib/admin.php


<?php
class Admin extends Base
{
public function __construct($name)
{
$this->name = $name;
}
}```

Fichero lib/user.php

<?php
class User extends Base
{
    public function __construct($name)
    {
        $this->name = $name;
    }
}```


Fichero lib/guest.php



<?php
class Guest extends Base
{
protected $name = 鈥業nvitado鈥;
}```

Fichero index.php

<?php

// @alejandro Incluir clases.
require_once('lib/base.php');
require_once('lib/admin.php');
require_once('lib/user.php');
require_once('lib/guest.php');


// @alejandro Mostrar contenido.
$guest = new Guest();
echo $guest->login();

$user = new User('Alex');
echo $user->login();

$admin = new Admin('Alejandro');
echo $admin->login();```

Polimorfismo: interfaz

El polimorfismo es exactamente una cosa que tiene diferentes comportamientos, es una capacidad o virtud, que al tener un 煤nico elemento se comporta de diferentes maneras y que de acuerdo a su configuraci贸n arrojar diferentes resultados.

Un ejemplo ser铆a cuando tenemos un m茅todo get el cual nos puede retornar datos en json como en xml, nos lleva a decir que es polimorfismo.
Pues el mismo m茅todo se esta comportando de diferentes formas, otorgando diferentes resultados

<?php

    interface Search
    {
        public function all();
    }


    class User implements Search
    {
        public function all()
        {
            return "Obteniendo a los Usuarios, XML";
        }
    }

    class Post implements Search
    {
        public function all()
        {
            return "Obteniendo a los Post, JSON";
        }
    }

    # Creamos el objeto
    $user = new User();
    echo $user->all();


    $post = new Post();
    echo $post->all();

?>

Clase Base

<?php

abstract class Base
{
    protected $name;

    private function getClassName()
    {
        return get_called_class();
    }

    public function login()
    {
        return "Mi nombre es $this->name desde la clase {$this->getClassName()}";
    }
}```

Clase Guet

<?php

require_once 鈥榖ase.php鈥;

class Guest extends Base
{
protected $name = 鈥業nvitado鈥;
}

Clase Admin

<?php

require_once 鈥榖ase.php鈥;

class Admin extends Base
{
public function __construct($name)
{
$this->name = $name;
}
}

Clase User

<?php

require_once 鈥榖ase.php鈥;

class User extends Base
{
public function __construct($name)
{
$this->name = $name;
}
}

Index

<?php

require_once 鈥榞uest.php鈥;
require_once 鈥榰ser.php鈥;
require_once 鈥榓dmin.php鈥;

$guest = new Guest();
echo $guest->login();

$guest = new User(鈥業talo鈥);
echo $guest->login();

$guest = new Admin(鈥楲ynda鈥);
echo $guest->login();