PHP OOP - Clases abstractas
PHP - ¿Qué son las clases y métodos abstractos?
Las clases y métodos abstractos son cuando la clase principal tiene un método con nombre, pero necesita su(s) clase(s) secundaria(s) para completar las tareas.
Una clase abstracta es una clase que contiene al menos un método abstracto. Un método abstracto es un método que se declara, pero no se implementa en el código.
Una clase o método abstracto se define con la abstract
palabra clave:
Sintaxis
<?php
abstract class
ParentClass {
abstract public function someMethod1();
abstract public function someMethod2($name, $color);
abstract
public function someMethod3() : string;
}
?>
Al heredar de una clase abstracta, el método de la clase secundaria debe definirse con el mismo nombre y el mismo modificador de acceso restringido o menos. Entonces, si el método abstracto se define como protegido, el método de la clase secundaria debe definirse como protegido o público, pero no privado. Además, el tipo y el número de argumentos requeridos deben ser los mismos. Sin embargo, las clases secundarias pueden tener además argumentos opcionales.
Entonces, cuando una clase secundaria se hereda de una clase abstracta, tenemos las siguientes reglas:
- El método de la clase secundaria debe definirse con el mismo nombre y vuelve a declarar el método abstracto principal.
- El método de la clase secundaria debe definirse con el mismo modificador de acceso o uno menos restringido.
- El número de argumentos requeridos debe ser el mismo. Sin embargo, la clase secundaria puede tener argumentos opcionales además
Veamos un ejemplo:
Ejemplo
<?php
// Parent class
abstract class Car {
public
$name;
public
function __construct($name) {
$this->name = $name;
}
abstract public function intro() : string;
}
// Child classes
class
Audi extends Car {
public
function intro() : string {
return "Choose German
quality! I'm an $this->name!";
}
}
class
Volvo extends Car {
public
function intro() : string {
return "Proud to be
Swedish! I'm a $this->name!";
}
}
class
Citroen extends Car {
public
function intro() : string {
return "French
extravagance! I'm a $this->name!";
}
}
// Create objects from the child classes
$audi = new
audi("Audi");
echo $audi->intro();
echo "<br>";
$volvo = new
volvo("Volvo");
echo $volvo->intro();
echo "<br>";
$citroen = new citroen("Citroen");
echo $citroen->intro();
?>
Ejemplo explicado
Las clases Audi, Volvo y Citroen se heredan de la clase Car. Esto significa que las clases Audi, Volvo y Citroen pueden usar la propiedad pública $name así como el método público __construct() de la clase Car debido a la herencia.
Pero, intro() es un método abstracto que debe definirse en todas las clases secundarias y deben devolver una cadena.
PHP - Más ejemplos de clases abstractas
Veamos otro ejemplo donde el método abstracto tiene un argumento:
Ejemplo
<?php
abstract class ParentClass {
// Abstract method
with an argument
abstract protected
function prefixName($name);
}
class ChildClass extends ParentClass {
public function prefixName($name) {
if ($name == "John Doe") {
$prefix = "Mr.";
} elseif ($name == "Jane Doe") {
$prefix =
"Mrs.";
} else {
$prefix = "";
}
return
"{$prefix} {$name}";
}
}
$class = new ChildClass;
echo $class->prefixName("John
Doe");
echo "<br>";
echo $class->prefixName("Jane Doe");
?>
Veamos otro ejemplo en el que el método abstracto tiene un argumento y la clase secundaria tiene dos argumentos opcionales que no están definidos en el método abstracto del padre:
Ejemplo
<?php
abstract class ParentClass {
// Abstract method
with an argument
abstract protected
function prefixName($name);
}
class ChildClass extends ParentClass {
// The child class may define optional arguments that are not in the parent's
abstract method
public function prefixName($name, $separator = ".",
$greet = "Dear") {
if ($name == "John Doe") {
$prefix = "Mr";
} elseif ($name == "Jane Doe") {
$prefix =
"Mrs";
} else {
$prefix = "";
}
return
"{$greet} {$prefix}{$separator} {$name}";
}
}
$class = new ChildClass;
echo $class->prefixName("John
Doe");
echo "<br>";
echo $class->prefixName("Jane Doe");
?>