Diferencia entre revisiones de «Plantilla:PHP/Herencia»

De WikiEducator
Saltar a: navegación, buscar
(Clases Abstractas)
 
(23 revisiones intermedias por el mismo usuario no mostrado)
Línea 1: Línea 1:
====Métodos ''static'' Vs ''no static''====
+
===Herencia===
*En php la idea de '''''static''''', es igual que en cualquier lenguaje de programación.
+
*La herencia es un mecanismo de programación que me permite crear una jerarquía en los componentes software, que se pueden ir especializando
*Cuando un elementos  (atributo o método), es estático, ese elemento es compartido por todos los objetos de la clase, y persiste en memoria con su contenido mientras haya un objeto de esa clase.
+
*Es principio de abstracción por el cual podemos crear una jerarquía de clases, donde tenemos la raíz con los elementos comunes y en los nodos vamos especializando clases.
*Como no es un elemento de cada objeto, sino de todos los objetos de una clase, también se le suelen llamar atributos o métodos de la clase.
+
*La idea es definir una clase con ciertas características comunes (atributos, métodos)
*Como no es de la clase para acceder a él necesitamos nombrar la clase. En php se puede hacer suando el operador '''''self''''' o incluso el propio nombre de la clase
+
Posteriormente crearemos otras clases a partir de la ya existente, quedando implícitamente los atributos y métodos como también parte de su estructura o composición.
  
*Es un ejemplo típico tener un atributo static que cuente cuantos objetos hay de una clase.
+
*Es una característica muy natural (p.e Personas (médicos y bailarines) vehículos (Terrestres (coche, moto) Acuáticos (barco, lancha))
*Miramos la siguiente imagen que trata de ilustrar  como al crear objetos se instancian en memoria
+
[[Archivo:Herencia.png]]
[[Archivo:estatico1.png]]
+
*Es una forma de obtener características comunes por separado y luego especializar evitando redundancias
*Cuando añadimos un elemento estático, solo habrá una copia en memoria y es compartida por todos los objetos de la clase
+
*Facilita la reusabilidad y adaptación
[[Archivo:estatico2.png]]
+
;La herenica implica declarar jerarquía de clases
*Vemos el código y como se accede al elemento
+
*En la raíz de la misma, establecemos la parte o estructura  común a dichas clases , y posteriormente vamos especializando las diferencias de cada clase
 +
[[Archivo:jerarquia_clases_1.png]]
  
 +
{{MRM_Puntos clave|
 +
:Todos los atributos y métodos de un supertipo o clase en nivel superior que sean públicos o '''''protegidos''''', son heredados  (son parte de ella) a todas las clases de nivel inferior.
 +
}}
 +
*Para establecer una jerarquía, usamos la palabra reservada '''''extends''''' en las clases que hereden.
 +
*Vamos a verlo con un ejemplo
 +
[[Archivo:jerarquia_ambulatoria_1.png]]
 +
*Primero establecemos la clase '''''Persona'''''
 
<source lang=php>
 
<source lang=php>
 
<?php
 
<?php
class Racional {
 
   
 
    static public $cuenta_racionales=0;
 
  
    //atributos
 
    private $num; //el numerador
 
    private $den; //el denominador
 
    //......
 
    public function __construct($num, $den) {
 
        self::$cuenta_racionales++;
 
    .......
 
  
</source>
+
class Persona
*El uso
+
{
<source lang = php>
+
    protected $nombre;
<?php
+
    protected $direccion;
 +
    protected $edad;
 +
    protected $frase;
  
/*
+
     public function __construct(string $n, string $d, string $e){
* To change this license header, choose License Headers in Project Properties.
+
* To change this template file, choose Tools | Templates
+
* and open the template in the editor.
+
*/
+
require_once "Racional.php";
+
      
+
   
+
    $r1 = new Racional(5,4);
+
    $r2 = new Racional(5,4);
+
    $r3 = new Racional(5,4);
+
    echo "<h1>Ahora tenemos ". Racional ::$cuenta_racionales." objetos racionales</h1>";
+
    $r4 = new Racional(5,4);
+
    $r5 = new Racional(5,4);
+
    echo "<h1>Ahora tenemos" .Racional::$cuenta_racionales."</h1>";
+
    $r6 = new Racional(5,4);
+
    $r7 = new Racional(5,4);
+
   
+
    //Observa (y esto es de php ) que puedo acceder a un elemento estático
+
    //A traves del nombre del objeto
+
    echo "<h1>Ahora tenemos" .Racional::$cuenta_racionales."</h1>";
+
    echo "<h1>Podemos acceder con los objtetos </h2>";
+
    echo "<h1>Según r1 tenemos " .$r1::$cuenta_racionales."</h1>";
+
    echo "<h1>Según r2 tenemos " .$r2::$cuenta_racionales."</h1>";
+
    echo "<h1>Según r3 tenemos " .$r3::$cuenta_racionales."</h1>";
+
    echo "<h1>Según r4 tenemos " .$r4::$cuenta_racionales."</h1>";
+
    echo "<h1>Según La clase tenemos " .Racional::$cuenta_racionales."</h1>";
+
   
+
   
+
   
+
   
+
?>
+
</source>
+
*La salida
+
[[Archivo:AppEstatica1.png]]
+
  
*Vamos a implementar las operaciones en un Racional.
+
    }
Primero como siempre conviene recordar cómo se hacen
+
 
[[Archivo:suma_racionales.png]]
+
     public function establecer_frase ($frase){
[[Archivo:resta_racionales.png]]
+
[[Archivo:mult_racionales.png]]
+
[[Archivo:div_racionales.png]]
+
*Si la operación la implemento como  un método no estático lo que estaría haciendo es sumar al objeto acutual, otro objeto Racional que pasamos como argumento. Puedo modificar el objeto acutal como resultado de la suma, o devolver otro objeto Racional que sería lo mas correcto
+
<source lang=php>
+
/**
+
    *
+
    * @param Racional $n1
+
    * @return \Racional
+
    * @description suma al racional actual, el racional que recibe como parámetro
+
    */
+
     public function sumar(Racional $n1) {
+
        $den = ($this->den * $n1->getDen());
+
        $num = ($this->den * $n1->getNum() + $this->num * $n1->getDen());
+
  
        return new Racional($num, $den);
 
 
     }
 
     }
</source>
 
*Para usarlo
 
<source lang=php>
 
....
 
$r1 = new Racional(7,6);
 
$r2 = new Racional(9,4);
 
 
 
  
$r3  = $r1->sumar($r2)
+
    public function hablar ($frase){
echo "$r1 + $r2 = $r3);
+
 
</source>
+
    }
*La salida
+
 
[[Archivo:sumarNoEstatico.png]]
+
}
  
*Si la operación la realizo como  un método estático lo que estaría haciendo es sumar dos objetos Racionales , devolviendo un nuevo objeto de tipo Racional Vamos
 
<source lang=php>
 
    static public function sum_static (Racional $r1, Racional $r2){
 
        $n = $r1->getNum()*$r2->getDen()+$r1->getDen()*$r2->getNum();
 
        $d = $r1->getDen()*$r2->getDen();
 
        return new Racional ($n, $d);
 
 
</source>
 
</source>
  
*Para usarlo
+
*Ahora establecemos la clase que hereda de persona
 +
{{MRM_Puntos clave|Title=Principios del uso de la herencia|
 +
;Todos los atributos y métodos públicos y protegidos del supertipo '''''Persona''''' son también de '''''Sanitario'''''
 +
;En un momento dado, podemos invocar a los métodos del supertipo usando el operador '''''parent''''' seguido del operador de resolución de ámbito '''''::'''''
 +
}}
 +
*Observa el código
 
<source lang=php>
 
<source lang=php>
....
+
<?php
$r1 = new Racional(7,6);
+
$r2 = new Racional(9,4);
+
 
+
  
$r3  = Racional::sum_static($r1,$r2);
+
class Sanitario extends Persona
echo "$r1 + $r2 = $r3);
+
{
</source>
+
    protected $centroSalud;
*La salida
+
    protected $yearTitulacion;
  
 +
    public function __construct(string $centro, string $year){
 +
        parent::__construct();
 +
        ....
  
 +
    }
 +
 +
 +
</source>
  
  
===Herencia===
 
*La herencia es un mecanismo de programación que me permite crear una jerarquía en los componentes software, que se pueden ir especializando
 
Se puede definir una clase  con ciertas características (atributos, métodos)
 
*Posteriormente puedo definir otra clase a partir de la ya existente, quedándo implícitamente los atributos y métodos como también parte de su estructura o composición
 
*Es una característica muy natural (p.e Personas (médicos y bailarines) vehículos (Terrestres (coche, moto) Acuáticos (barco, lancha))
 
[[Archivo:Herencia.png]]
 
*Es una forma de obtener características comunes por separado y luego especializar evitando redundancias
 
*Facilita la reusabilidad y adaptación
 
 
*Vemos dos ejemplos  para explicar de forma empírica este concepto
 
*Vemos dos ejemplos  para explicar de forma empírica este concepto
 
{{MRM_Ejemplo|Title= Herencia: gestión personal ambulatorio|
 
{{MRM_Ejemplo|Title= Herencia: gestión personal ambulatorio|
Línea 155: Línea 94:
 
*El digrama podría quedar
 
*El digrama podría quedar
 
[[Imagen:JerarquiaPersonaAmbulatorio.png|center|400px]]<br />
 
[[Imagen:JerarquiaPersonaAmbulatorio.png|center|400px]]<br />
 +
*Ver la aplicación ejecutándose
 +
http://manuel.infenlaces.com/dwes/ejercicios/T6_Ambulatorio/
 +
{{Plegable|hide|Posible index de uso |
 +
<source lang=php>
 +
<?php
 +
spl_autoload_register(function ($nombre_clase) {
 +
    include $nombre_clase . '.php';
 +
});
 +
 +
$medico1 = new Medica("María", "Martínez", "Casa de María", 29, "Cardiólogía");
 +
$medico2 = new Medica("Luis", "Pérez", "Casa de Luis", 38, "Pediatría");
 +
$medico3 = new Medica("Nieves", "Ruiz", "Casa de Nieves", 44, "Dermatología");
 +
$conserje = new Conserje("Soledad", "Viruela", "Casa de Soledad", 58, "Mostrador Entrada");
 +
$enfermera = new Enfermera("Javier", "Moreno", "Casa de Javier", "general", 1990);
 +
$enfermera2 = new Enfermera("Luis", "Perez", "Casa de Javier", "general", 1990);
 +
 +
 +
$conserje->avisoEnfermera($enfermera, "Realizar cura en brazo Señor Martínez NSS 50/2155441/35");
 +
 +
$enfermera->avisoMedico($medico3, "Paciente con toss y fiebre");
 +
 +
$enfermera2->avisoMedico($medico2, "Paciente con toss y fiebre");
 +
$enfermera2->avisoMedico($medico2, "Paciente con Vómitos");
 +
$enfermera2->avisoMedico($medico3, "Paciente con pie torcido, impresión de rotura");
 +
 +
 +
$conserje->avisoMedico($medico1, "Visitar en casa con mucha fiebre", "Visita");
 +
$conserje->avisoMedico($medico1, "Problemas para desplazarse ", "Visita");
 +
$conserje->avisoMedico($medico2, "Mareos y vétigos", "Visita");
 +
$conserje->avisoMedico($medico2, "Persona mayor con poca mobilidad", "Visita");
 +
$conserje->avisoMedico($medico3, "Niño pequeño con fiebre", "Visita");
 +
$conserje->avisoMedico($medico1, "Caída en el parque", "Consulta");
 +
?>
 +
 +
<html>
 +
    <head>
 +
        <meta charset="UTF-8">
 +
        <title></title>
 +
        <style type="text/css">
 +
 +
        </style>
 +
        <link rel="stylesheet" href="./stilo.css" type="text/css"/>
 +
    </head>
 +
    <body>
 +
        <?php
 +
        echo "$medico3";
 +
        echo "$medico1";
 +
        echo "$medico2";
 +
// put your code here
 +
        ?>
 +
    </body>
 +
</html>
 +
</source>
 +
 +
}}
 +
 +
<!--
 
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploAmbulatorio | Posible Solución]]</font>
 
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploAmbulatorio | Posible Solución]]</font>
 +
-->
 
<hr />
 
<hr />
 
}}
 
}}
====clases abstractas====
+
====Clases Abstractas====
*Es una situación particular que se presentan en muchas jerarquías
+
 
*Cuando realizamos jerarquías muchas veces encontramos métodos comunes a varias clases. Esto implicaría que ese método sería un método de una superclase o clase padre de la que luego se heredará
 
*Cuando realizamos jerarquías muchas veces encontramos métodos comunes a varias clases. Esto implicaría que ese método sería un método de una superclase o clase padre de la que luego se heredará
 
*Pero puede ocurrir que aunque el concepto del método es común a todas las clases,la forma de implementarla es particular en cada una de ellas.
 
*Pero puede ocurrir que aunque el concepto del método es común a todas las clases,la forma de implementarla es particular en cada una de ellas.
 +
{{MRM_Ejemplo|Title=clase abstracta|
 +
 +
 +
 +
 +
}}
 +
 +
 +
 
*En este caso, la forma correcta de proceder, es especificar el método el la clase superior, e implementar el código en cada una de las clases que derivo.
 
*En este caso, la forma correcta de proceder, es especificar el método el la clase superior, e implementar el código en cada una de las clases que derivo.
 
*El método especificado en la clase superior sería un método sin código, conocido como un método abstracto, y la clase dónde se especifica pasa a ser abstracta
 
*El método especificado en la clase superior sería un método sin código, conocido como un método abstracto, y la clase dónde se especifica pasa a ser abstracta
Línea 184: Línea 189:
 
#dibujar el polígono (Esto insertaremos un pequeño código de javascript de uso básico del canvas
 
#dibujar el polígono (Esto insertaremos un pequeño código de javascript de uso básico del canvas
 
#conocer el número de lados del polígono.
 
#conocer el número de lados del polígono.
 +
[[Archivo:app_geometria.png]]
 
*Realizamos los siguientes clases  
 
*Realizamos los siguientes clases  
 
;Clase Polígono
 
;Clase Polígono
 
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Poligono | Descripción de la Clase Polígono]]</font>
 
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Poligono | Descripción de la Clase Polígono]]</font>
 +
 
<hr />
 
<hr />
 
;Clase Rectángulo
 
;Clase Rectángulo
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Rectangulo | Descripción de la Clase Rectángulo]]</font>
+
 
 +
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Rectangulo |  
 +
 
 +
Descripción de la Clase Rectángulo]]</font>
 +
 
 
<hr />
 
<hr />
 
;Clase Cuadrado
 
;Clase Cuadrado
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Cuadrado | Descripción de la Clase Cuadrado]]</font>
+
 
 +
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Cuadrado |  
 +
 
 +
Descripción de la Clase Cuadrado]]</font>
 
<hr />
 
<hr />
  
 
;Clase Triangulo
 
;Clase Triangulo
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Triangulo | Descripción de la Clase Triángulo]]</font>
+
 
 +
 
 +
<font size<nowiki>=</nowiki>5 color<nowiki>=</nowiki>red>[[Usuario:ManuelRomero/ProgramacionWeb/php/POO/Herencia/EjemploGeometria/Triangulo |  
 +
 
 +
Descripción de la Clase Triángulo]]</font>
 
<hr />
 
<hr />
 
;Uso de esta aplicación
 
;Uso de esta aplicación

Última revisión de 17:26 23 may 2023

Herencia

  • La herencia es un mecanismo de programación que me permite crear una jerarquía en los componentes software, que se pueden ir especializando
  • Es principio de abstracción por el cual podemos crear una jerarquía de clases, donde tenemos la raíz con los elementos comunes y en los nodos vamos especializando clases.
  • La idea es definir una clase con ciertas características comunes (atributos, métodos)

Posteriormente crearemos otras clases a partir de la ya existente, quedando implícitamente los atributos y métodos como también parte de su estructura o composición.

  • Es una característica muy natural (p.e Personas (médicos y bailarines) vehículos (Terrestres (coche, moto) Acuáticos (barco, lancha))

Herencia.png

  • Es una forma de obtener características comunes por separado y luego especializar evitando redundancias
  • Facilita la reusabilidad y adaptación
La herenica implica declarar jerarquía de clases
  • En la raíz de la misma, establecemos la parte o estructura común a dichas clases , y posteriormente vamos especializando las diferencias de cada clase

Jerarquia clases 1.png



Icon key points.gif

Puntos clave

Todos los atributos y métodos de un supertipo o clase en nivel superior que sean públicos o protegidos, son heredados (son parte de ella) a todas las clases de nivel inferior.


  • Para establecer una jerarquía, usamos la palabra reservada extends en las clases que hereden.
  • Vamos a verlo con un ejemplo

Jerarquia ambulatoria 1.png

  • Primero establecemos la clase Persona
<?php
 
 
class Persona
{
    protected $nombre;
    protected $direccion;
    protected $edad;
    protected $frase;
 
    public function __construct(string $n, string $d, string $e){
 
    }
 
    public  function establecer_frase ($frase){
 
    }
 
    public function hablar ($frase){
 
    }
 
}
  • Ahora establecemos la clase que hereda de persona


Icon key points.gif

Principios del uso de la herencia

Todos los atributos y métodos públicos y protegidos del supertipo Persona son también de Sanitario
En un momento dado, podemos invocar a los métodos del supertipo usando el operador parent seguido del operador de resolución de ámbito ::


  • Observa el código
<?php
 
class Sanitario extends Persona
{
    protected $centroSalud;
    protected $yearTitulacion;
 
    public function __construct(string $centro, string $year){
        parent::__construct();
        ....
 
    }


  • Vemos dos ejemplos para explicar de forma empírica este concepto


Icon casestudy.gif
Herencia: gestión personal ambulatorio
  • Se pide gestionar un ambulatorio.
  • Para ello vamos a hacer sólo el diagrama de clases y su implementación.
  • Lo hacemos a nivel básico (sin entrar en detalles).
  • Tras realizar un análisis se determina que se pretende gestionar:
los datos de los empleados y anotar las acciones básicas que realizan.
  • Encontramos los siguientes elementos que especificamos como clases
Conserjes
Enfermeras
Médicas
Las propiedades (atributos) y métodos de cada clase se especifican
en los siguientes diagramas de clases
  • Claramente vemos que todos ellos tienen varios elementos en común.
  • Esto nos permite crear una clases genérica que por ejemplo podemos llamar personalAmbulatorio
  • Posteriormente creamos una especialización de personalAmbulatorio con los elementos particulares
  • El digrama podría quedar
JerarquiaPersonaAmbulatorio.png

  • Ver la aplicación ejecutándose
http://manuel.infenlaces.com/dwes/ejercicios/T6_Ambulatorio/


Clases Abstractas

  • Cuando realizamos jerarquías muchas veces encontramos métodos comunes a varias clases. Esto implicaría que ese método sería un método de una superclase o clase padre de la que luego se heredará
  • Pero puede ocurrir que aunque el concepto del método es común a todas las clases,la forma de implementarla es particular en cada una de ellas.


Icon casestudy.gif
clase abstracta






  • En este caso, la forma correcta de proceder, es especificar el método el la clase superior, e implementar el código en cada una de las clases que derivo.
  • El método especificado en la clase superior sería un método sin código, conocido como un método abstracto, y la clase dónde se especifica pasa a ser abstracta


Icon define.gif
Clase Abstracta

Es aquella clase que tiene un método o más abstracto



Icon define.gif
Método Abstracto
  • Es un método que no tiene código asociado
  • El código se implementará en las clases derivadas



Icon key points.gif

Puntos clave

Nunca podremos instanciar un objeto de una clase abstracta
  • Esto es normal, ya que ese objeto no tendría instrucciones para su/s método/s abstracto/s



  • Vamos a platear un ejemplo



Icon casestudy.gif
App de Geometría
Gestionar figuras geométricas de tipo triángulo, cuadrado y Rectángulo.
  • De ellas queremos conocer:
  1. el número de lados.
  2. calcular el área.
  3. dibujar el polígono (Esto insertaremos un pequeño código de javascript de uso básico del canvas
  4. conocer el número de lados del polígono.

App geometria.png

  • Realizamos los siguientes clases
Clase Polígono

Descripción de la Clase Polígono


Clase Rectángulo

Descripción de la Clase Rectángulo


Clase Cuadrado

Descripción de la Clase Cuadrado


Clase Triangulo


Descripción de la Clase Triángulo


Uso de esta aplicación
  • Un posible código index.php que lo único que hace es crear objetos y visulizar su área y dibujarlos
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <?php
        spl_autoload_register(function ($clase){
            require "$clase.php";
        });
 
        $triangulo = new Triangulo(200,300);
        $cuadrado = new Cuadrado(200);
        $rectangulo = new Rectangulo(200,100);
 
        echo "<h4>Triángulo,  ". Poligono::lados($triangulo)." y área ".
                $triangulo->area()." px<sup>2</sup></h4>";
 
        echo "<h4>Cuadrado, ". Poligono::lados($cuadrado)." y área ".
                $cuadrado->area()." px<sup>2</sup></h4>";
        echo "<h4>Rectángulo, ". Poligono::lados($rectangulo)." y área ".
                $rectangulo->area()." px<sup>2</sup></h4>";
 
        echo $triangulo->dibuja();
        echo $cuadrado->dibuja();
        echo $rectangulo->dibuja();
 
 
        ?>
    </body>
</html>
Resultado de su ejecución

AppGeometria.png


V