13 - Sobreescritura de métodos.


Una subclase en PHP puede redefinir un método, es decir que podemos crear un método con el mismo nombre que el método de la clase padre. Ahora cuando creamos un objeto de la subclase, el método que se llamará es el de dicha subclase.

Lo más conveniente es sobreescribir métodos para completar el algoritmo del método de la clase padre. No es bueno sobreescribir un método y cambiar completamente su comportamiento.

Veamos nuestro problema de las tres clases: Operacion, Suma y Resta. Sobreescribiremos en las subclases el método imprimirResultado (el objetivo es que muestre un título indicando si se trata del resultado de la suma de dos valores o el resultado de la diferencia de dos valores)

pagina1.php

<html>
<head>
<title>Pruebas</title>
</head>
<body>
<?php
class Operacion {
  protected $valor1;
  protected $valor2;
  protected $resultado;
  public function cargar1($v)
  {
    $this->valor1=$v;
  }
  public function cargar2($v)
  {
    $this->valor2=$v;
  }
  public function imprimirResultado()
  {
    echo $this->resultado.'<br>';
  }
}

class Suma extends Operacion{
  public function operar()
  {
    $this->resultado=$this->valor1+$this->valor2;
  }
  public function imprimirResultado()
  {
    echo "La suma de $this->valor1 y $this->valor2 es:";
    parent::imprimirResultado();
  }
}

class Resta extends Operacion{
  public function operar()
  {
    $this->resultado=$this->valor1-$this->valor2;
  }
  public function imprimirResultado()
  {
    echo "La diferencia de $this->valor1 y $this->valor2 es:";
    parent::imprimirResultado();
  }
}

$suma=new Suma();
$suma->cargar1(10);
$suma->cargar2(10);
$suma->operar();
$suma->imprimirResultado();

$resta=new Resta();
$resta->cargar1(10);
$resta->cargar2(5);
$resta->operar();
$resta->imprimirResultado();
?>
</body>
</html> 

La clase operación define el método imprimirResultado:

class Operacion {
...
  public function imprimirResultado()
  {
    echo $this->resultado.'<br>';
  }

Luego la subclase sobreescribe dicho método (es decir define otro método con el mismo nombre):

class Suma extends Operacion {
...
  public function imprimirResultado()
  {
    echo "La suma de $this->valor1 y $this->valor2 es:";
    parent::imprimirResultado();
  }

Esto hace que cuando definamos un objeto de la clase Suma se llamará el método sobreescrito (es decir el de la clase Suma):

$suma=new Suma();
$suma->cargar1(10);
$suma->cargar2(10);
$suma->operar();
$suma->imprimirResultado(); //Se llama el método imprimirResultado de la clase Suma

Pero si observamos nuevamente el método imprimirResultado de la clase Suma podemos ver que desde el mismo se llama al método imprimirResultado de la clase Operacion con la siguiente sintaxis:

    parent::imprimirResultado();

La palabra clave parent indica que se llama a un método llamado imprimirResultado de la clase padre y no se está llamando recursivamente.

Sería incorrecto si llamamos con la siguiente sintaxis:

$this->imprimirResultado();

Con esta sintaxis estamos llamando en forma recursiva al mísmo método.

Como podemos analizar hemos llevado el título que indica si se trata de una suma o resta a la clase respectiva (no podemos definir dicho título en la clase Operacion y por eso tuvimos que sobreescribir el método imprimirResultado)

Retornar