No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Polimorfismo: interfaz

11/19
Recursos

Aportes 59

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

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 “fancys” y “profesionales” 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 “extends” e “implements”, 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/>";
    }
}
Creo que estos cursos de POO tendrian mas sentido si fueran con proyectos reales no con superheroes, michis o palabras sueltas. Algo que permita afianzar y aprender de forma mas profunda. El instructor es muy bueno se nota, como muchos en Platzi pero precisamente encuentro un poco complejo aprender con temas sin secuencia o relacion.

Una clase es como un plano para construir un objeto, mientras que una interfaz es como un contrato que define qué métodos debe implementar una clase.

  • Clase:

    • Una clase en PHP es un molde para crear objetos. Contiene propiedades y métodos que definen el comportamiento y las características de esos objetos.

    • Dentro de una clase, puedes definir propiedades (variables) y métodos (funciones) que representan el estado y el comportamiento del objeto.

    • Puedes crear múltiples instancias u objetos basados en una misma clase, y cada objeto tendrá su propio conjunto de valores de propiedades.

    • Ejemplo:

      class Coche {
          public $marca;
          public $modelo;
      
          public function encender() {
              echo "El coche está encendido.";
          }
      
          public function apagar() {
              echo "El coche está apagado.";
          }
      }
      
  • Interfaz:

    • Una interfaz en PHP define un conjunto de métodos que una clase debe implementar. Es como un contrato que asegura que cualquier clase que implemente esa interfaz proporcionará la funcionalidad especificada.

    • Las interfaces son útiles cuando deseas establecer un comportamiento común entre diferentes clases que no necesariamente tienen una relación de herencia común.

    • No puedes definir propiedades dentro de una interfaz, solo métodos.

    • Ejemplo:

      interface Conduccion {
          public function acelerar();
          public function frenar();
      }
      
    • Una clase que implemente esta interfaz debe proporcionar implementaciones concretas para los métodos acelerar() y frenar(). Por ejemplo:

      class CocheDeportivo implements Conduccion {
          public function acelerar() {
              echo "El coche deportivo está acelerando.";
          }
      
          public function frenar() {
              echo "El coche deportivo está frenando.";
          }
      }
      

Una clase es un plano para crear objetos que encapsulan estado y comportamiento, mientras que una interfaz es un contrato que define qué métodos debe proporcionar una clase. Las clases pueden implementar múltiples interfaces pero solo pueden heredar de una sola clase (en PHP).

```js name} desde la clase {$this -> getClassName()}"; } } $guest = new Guest(); echo $guest -> login(); echo '
'; $user = new User('Diego'); echo $user -> login(); echo '
'; $user = new User('Isaac'); echo $user -> login(); ```
```js base = $base_ext; $this->altura = $altura_ext; } public function area(){ $resultado = 'El área depende del tipo de valor'; return $resultado; } public function getBase(){ return $this->base; } public function getAltura(){ return $this->altura; } } //clase heredera: Rectangulo class Rectangulo extends Figura { public function area(){ $area = $this->base * $this->altura; $resultado = '

Rectángulo

'; $resultado .= '
'; $resultado .= 'Altura del Rectángulo = '.$this->getAltura().'cm'; $resultado .= '
'; $resultado .= 'Base del Rectángulo = '.$this->getBase().'cm'; $resultado .= '
'; $resultado .= 'Área del Rectángulo = '.$area.'cm2'; $resultado .= '
'; $resultado .= '
'; return $resultado; } } //clase heredera: Triángulo class Triangulo extends Figura { public function area(){ $area = $this->base * $this->altura / 2; $resultado = '

Triángulo

'; $resultado .= '
'; $resultado .= 'Altura del Triángulo = '.$this->getAltura().'cm'; $resultado .= '
'; $resultado .= 'Base del Triángulo = '.$this->getBase().'cm'; $resultado .= '
'; $resultado .= 'Área del Triángulo = '.$area.'cm2'; $resultado .= '
'; $resultado .= '
'; return $resultado; } } //clase heredera: Cuadrado class Cuadrado extends Figura { public function area(){ $area = $this->base * $this->altura; $resultado = '

Cuadrado

'; $resultado .= '
'; $resultado .= 'Altura del Cuadrado = '.$this->getAltura().'cm'; $resultado .= '
'; $resultado .= 'Base del Cuadrado = '.$this->getBase().'cm'; $resultado .= '
'; $resultado .= 'Área del Cuadrado = '.$area.'cm2'; $resultado .= '
'; $resultado .= '
'; return $resultado; } } //clase heredera: Trapecio class Trapecio extends Figura{ protected $base2; function __construct($base_ext,$altura_ext,$base2_ext) { $this->base = $base_ext; $this->altura = $altura_ext; $this->base2 = $base2_ext; } function area(){ $area = (($this->base + $this->base2) / 2) * $this->altura; $resultado = '

Trapecio

'; $resultado .= '
'; $resultado .= 'Altura del Trapecio = '.$this->getAltura().'cm'; $resultado .= '
'; $resultado .= 'Base Inferior del Trapecio = '.$this->getBase().'cm'; $resultado .= '
'; $resultado .= 'Base Superior del Trapecio = '.$this->getBase2().'cm'; $resultado .= '
'; $resultado .= 'Área del Trapecio = '.$area.'cm2'; $resultado .= '
'; $resultado .= '
'; return $resultado; } public function getBase2(){ return $this->base2; } } function calculaArea(Figura $objeto){ print $objeto->area(); } $rectangulo = new Rectangulo(15,35); $triangulo = new Triangulo(5,3); $cuadrado = new Cuadrado(20,20); $trapecio = new Trapecio(6,3,4); calculaArea($rectangulo); calculaArea($triangulo); calculaArea($cuadrado); calculaArea($trapecio); ?> ```
un poco de código:

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 “Base.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) = ‘IResository’, luego la implementacion ‘Repository’ 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(‘Marlon’);
echo $user->login();

$admin = new Admin(‘Andres’);
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 = ‘Invitado’;
}

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 “ladrar” o “guaf” (no se como representar el sonido XD) luego en la clase gato regresaria “maullar” o “miaauuu” y en la vaca regresaria “mugir” o “muuuu” (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 “requerirlos” 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:
“En 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 ‘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 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 = ‘Invitado’;
}```

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 ‘base.php’;

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

Clase Admin

<?php

require_once ‘base.php’;

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

Clase User

<?php

require_once ‘base.php’;

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

Index

<?php

require_once ‘guest.php’;
require_once ‘user.php’;
require_once ‘admin.php’;

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

$guest = new User(‘Italo’);
echo $guest->login();

$guest = new Admin(‘Lynda’);
echo $guest->login();