Clases abstractas vs interfaces en PHP
Clases abstractas
Las clases abstractas son una clase que tiene 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. La clase que hereda esta clase abstracta necesita definir ese método. Debe haber una palabra clave abstracta que se debe devolver antes de esta clase para que sea considerada de clases abstractas. Por tanto, no podemos crear objetos a partir de clases abstractas. En su lugar, necesitamos crear clases secundarias que agreguen el código a los cuerpos de los métodos y usar estas clases secundarias para crear objetos. Puede haber más de un método que puede dejarse sin definir.
// abstract class abstract class DataAccess { public $varAbstract; protected $varHost; // this abstract method confirm need to define in child class abstract function db_connect(); protected function getResultArray(){ }}
La interfaz
Piense en una interfaz como una plantilla o contrato para sus clases concretas. La clase que es completamente abstracta se llama interfaz. Cualquier clase que implemente esta interfaz debe usar la palabra clave implements y todos los métodos que se declaran en la clase deben definirse aquí. de lo contrario, esta clase también debe definirse como abstracta. Cuando una o más clases utilizan la misma interfaz, se denomina “polimorfismo”.
// interfaceinterface class DataInterface { public function insertData($varDataRecord); public function deleteData($varRecordId);}interface class DataFilterInterface { public function getList($varFilter);}
Implementación de clases abstractas e interfaces
Si tuviéramos que intentar crear una instancia de la clase Data_Access
como un objeto independiente:
Por tanto, no podemos crear objetos a partir de clases abstractas. En su lugar, necesitamos crear clases secundarias que agreguen el código a los cuerpos de los métodos y usar estas clases secundarias para crear objetos.
$cDataAccess = new Data_Access;
Lanzaría el siguiente error:
PHP Fatal error: Uncaught Error: Cannot instantiate abstract class Data_Access ...// Concrete class extend abstract and implement interfacesclass Customers extend DataAccess implements DataInterface,DataFilterInterface {public function __construct(){ $this->db_connect();}// inherited interface class public function insertData($varDataRecord){ }// inherited interface class public function deleteData($varRecordId){ }// inherited interface class public function getList($varFilter){ }}
Debido a que la interfaz aplica su regla de implementación, si intentara omitir una de las funciones en Customers
, por ejemplo insertRecord
, e intentara crear una instancia de ella, recibiríamos un error fatal:
PHP Fatal error: Class Customers contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Data_Interface::insertRecord)
Diferencia entre abstracto e interfaz
Las clases abstractas y la interfaz de PHP son similares a las de otros lenguajes OOPs. Las principales diferencias en el punto de vista de la programación son:
1. En clases abstractas no es necesario que todos los métodos sean abstractos. Pero en la interfaz, cada método es abstracto.
2. El método de la interfaz php debe ser público, pero no puede tener un modificador de acceso por defecto, todo se asume como público. El método en la clase abstracta en php podría ser público o estar protegido ambos.
3. La interfaz admite herencia múltiple, pero las dosis de clases abstractas no admiten herencia múltiple
Significa que puede extender una interface
con una o más (por lo tanto, de herencia múltiple) interfaces como:
interface Interface_A { } interface Interface_B { } interface Interface_C { } interface MyInterface extends Interface_A, Interface_B, Interface_C { }
Como puede verse, estamos ampliando MyInterface
con otras tres interfaces: Interface_A
, Interface_A
y Interface_C
.
Intentemos ahora extender una abstract class
:
class Class_A { } abstract class MyAbstractClass extends Class_A { }
No hay problema, PUEDE extender una clase abstracta con exactamente una clase, pero si intenta agregar una más:
class Class_A { } class Class_B { } abstract class MyAbstractClass extends Class_A, Class_B { }
Esta vez PHP le daría un error extraño sin decirle qué está haciendo mal:
Parse error: syntax error, unexpected ',', expecting '{'
Desearía que PHP hubiera dado un mensaje similar (espero que PHP proporcione mensajes de error más inteligentes en futuras versiones):
Fatal Error: You cannot extend an abstract class with more than one classes
4. Una interfaz contiene sólo miembros incompletos, pero también miembros completos y abstractos incompletos (resumen).
5. La interfaz no contiene un constructor, pero el resumen puede contener un constructor
6. El miembro de la interfaz no puede ser estático en abstracto, solo el miembro completo puede ser estático
abstract class MyAbstractClass { public static $foo = null; public static function foo() {} }abstract class MyAbstractClass { public static $foo = null; abstract static function foo() {} // error }