Programación orientada a objetos en PHP
Podemos imaginar nuestro universo hecho de diferentes objetos como el sol, la tierra, la luna, etc. De manera similar, podemos imaginar nuestro automóvil hecho de diferentes objetos como volante, dirección, engranaje, etc. De la misma manera, existen conceptos de programación orientados a objetos que asumen todo como un objeto y implementar un software utilizando diferentes objetos.
Conceptos orientados a objetos
Antes de entrar en detalle, definamos términos importantes relacionados con la programación orientada a objetos.
Class- Este es un tipo de datos definido por el programador, que incluye funciones locales así como datos locales. Puede pensar en una clase como una plantilla para crear muchas instancias del mismo tipo (o clase) de objeto.
Object- Una instancia individual de la estructura de datos definida por una clase. Define una clase una vez y luego crea muchos objetos que le pertenecen. Los objetos también se conocen como instancia.
Member Variable- Estas son las variables definidas dentro de una clase. Estos datos serán invisibles para el exterior de la clase y se puede acceder a ellos a través de funciones miembro. Estas variables se denominan atributo del objeto una vez que se crea un objeto.
Member function - Estas son las funciones definidas dentro de una clase y se utilizan para acceder a los datos del objeto.
Inheritance- Cuando una clase se define heredando la función existente de una clase padre, se llama herencia. Aquí la clase secundaria heredará todas o algunas funciones miembro y variables de una clase principal.
Parent class- Una clase heredada por otra clase. Esto también se denomina clase base o superclase.
Child Class- Una clase que hereda de otra clase. Esto también se denomina subclase o clase derivada.
Polymorphism- Este es un concepto orientado a objetos donde la misma función puede usarse para diferentes propósitos. Por ejemplo, el nombre de la función seguirá siendo el mismo, pero tomará un número diferente de argumentos y puede realizar una tarea diferente.
Overloading- un tipo de polimorfismo en el que algunos o todos los operadores tienen diferentes implementaciones dependiendo de los tipos de sus argumentos. De manera similar, las funciones también pueden sobrecargarse con una implementación diferente.
Data Abstraction - Cualquier representación de datos en la que los detalles de implementación estén ocultos (abstraídos).
Encapsulation - se refiere a un concepto en el que encapsulamos todos los datos y funciones miembro juntos para formar un objeto.
Constructor - se refiere a un tipo especial de función que se llamará automáticamente siempre que haya una formación de objeto de una clase.
Destructor - se refiere a un tipo especial de función que se llamará automáticamente siempre que un objeto se elimine o salga de su alcance.
Definición de clases PHP
La forma general para definir una nueva clase en PHP es la siguiente:
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
Aquí está la descripción de cada línea:
La forma especial class, seguido del nombre de la clase que desea definir.
Un conjunto de llaves que encierran cualquier número de declaraciones de variables y definiciones de funciones.
Las declaraciones de variables comienzan con la forma especial var, que va seguido de un nombre de variable $ convencional; también pueden tener una asignación inicial a un valor constante.
Las definiciones de funciones se parecen mucho a las funciones PHP independientes, pero son locales de la clase y se usarán para configurar y acceder a datos de objetos.
Ejemplo
Aquí hay un ejemplo que define una clase de tipo Libros:
<?php
class Books {
/* Member variables */
var $price;
var $title;
/* Member functions */
function setPrice($par){
$this->price = $par;
}
function getPrice(){
echo $this->price ."<br/>";
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title ." <br/>";
}
}
?>
La variable $thises una variable especial y se refiere al mismo objeto, es decir. sí mismo.
Creando objetos en PHP
Una vez que haya definido su clase, podrá crear tantos objetos como desee de ese tipo de clase. A continuación se muestra un ejemplo de cómo crear un objeto usandonew operador.
$physics = new Books;
$maths = new Books;
$chemistry = new Books;
Aquí hemos creado tres objetos y estos objetos son independientes entre sí y tendrán su existencia por separado. A continuación, veremos cómo acceder a la función miembro y procesar las variables miembro.
Funciones de miembros de llamada
Después de crear sus objetos, podrá llamar a funciones miembro relacionadas con ese objeto. Una función miembro solo podrá procesar la variable miembro del objeto relacionado.
El siguiente ejemplo muestra cómo establecer el título y los precios de los tres libros llamando a funciones miembro.
$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );
$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );
Ahora llama a otras funciones miembro para obtener los valores establecidos en el ejemplo anterior:
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
Esto producirá el siguiente resultado:
Physics for High School
Advanced Chemistry
Algebra
10
15
7
Funciones de constructor
Las funciones de constructor son un tipo especial de funciones que se llaman automáticamente cada vez que se crea un objeto. Así que aprovechamos al máximo este comportamiento, inicializando muchas cosas mediante funciones constructoras.
PHP proporciona una función especial llamada __construct()para definir un constructor. Puede pasar tantos argumentos como desee a la función constructora.
El siguiente ejemplo creará un constructor para la clase Books e inicializará el precio y el título del libro en el momento de la creación del objeto.
function __construct( $par1, $par2 ) {
$this->title = $par1;
$this->price = $par2;
}
Ahora no necesitamos llamar a la función set por separado para establecer el precio y el título. Podemos inicializar estas dos variables miembro solo en el momento de la creación del objeto. Verifique el siguiente ejemplo a continuación:
$physics = new Books( "Physics for High School", 10 );
$maths = new Books ( "Advanced Chemistry", 15 );
$chemistry = new Books ("Algebra", 7 );
/* Get those set values */
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
Esto producirá el siguiente resultado:
Physics for High School
Advanced Chemistry
Algebra
10
15
7
Incinerador de basuras
Como una función de constructor, puede definir una función de destructor usando function __destruct(). Puede liberar todos los recursos dentro de un destructor.
Herencia
Las definiciones de clases de PHP pueden heredar opcionalmente de una definición de clase principal mediante el uso de la cláusula amplía. La sintaxis es la siguiente:
class Child extends Parent {
<definition body>
}
El efecto de la herencia es que la clase secundaria (o subclase o clase derivada) tiene las siguientes características:
Tiene automáticamente todas las declaraciones de variables miembro de la clase padre.
Automáticamente tiene todas las mismas funciones miembro que el padre, que (por defecto) funcionará de la misma manera que esas funciones en el padre.
El siguiente ejemplo hereda la clase Books y agrega más funcionalidad según el requisito.
class Novel extends Books {
var $publisher;
function setPublisher($par){
$this->publisher = $par;
}
function getPublisher(){
echo $this->publisher. "<br />";
}
}
Ahora, aparte de las funciones heredadas, la clase Novel mantiene dos funciones miembro adicionales.
Anulación de función
Las definiciones de funciones en las clases secundarias anulan las definiciones con el mismo nombre en las clases principales. En una clase secundaria, podemos modificar la definición de una función heredada de la clase principal.
En el siguiente ejemplo, las funciones getPrice y getTitle se anulan para devolver algunos valores.
function getPrice() {
echo $this->price . "<br/>";
return $this->price;
}
function getTitle(){
echo $this->title . "<br/>";
return $this->title;
}
Miembros públicos
A menos que especifique lo contrario, las propiedades y métodos de una clase son públicos. Es decir, se puede acceder a ellos en tres situaciones posibles:
Desde fuera de la clase en la que se declara
Desde dentro de la clase en la que se declara
Desde dentro de otra clase que implementa la clase en la que se declara
Hasta ahora hemos visto a todos los miembros como miembros públicos. Si desea limitar la accesibilidad de los miembros de una clase, defina los miembros de la clase comoprivate o protected.
Miembros privados
Al designar un miembro como privado, limita su accesibilidad a la clase en la que está declarado. No se puede hacer referencia al miembro privado desde clases que heredan la clase en la que está declarado y no se puede acceder a él desde fuera de la clase.
Un miembro de la clase se puede convertir en privado usando private palabra clave delante del miembro.
class MyClass {
private $car = "skoda";
$driver = "SRK";
function __construct($par) {
// Statements here run every time
// an instance of the class
// is created.
}
function myPublicFunction() {
return("I'm visible!");
}
private function myPrivateFunction() {
return("I'm not visible outside!");
}
}
Cuando la clase MyClass es heredada por otra clase que usa extensions, myPublicFunction () será visible, al igual que $ driver. La clase que se extiende no tendrá conocimiento ni acceso a myPrivateFunction y $ car, porque están declarados privados.
Miembros protegidos
Se puede acceder a una propiedad o método protegido en la clase en la que se declara, así como en las clases que amplían esa clase. Los miembros protegidos no están disponibles fuera de esos dos tipos de clases. Un miembro de la clase puede protegerse usandoprotected palabra clave delante del miembro.
Aquí hay una versión diferente de MyClass:
class MyClass {
protected $car = "skoda";
$driver = "SRK";
function __construct($par) {
// Statements here run every time
// an instance of the class
// is created.
}
function myPublicFunction() {
return("I'm visible!");
}
protected function myPrivateFunction() {
return("I'm visible in child class!");
}
}
Interfaces
Las interfaces se definen para proporcionar nombres de funciones comunes a los implementadores. Diferentes implementadores pueden implementar esas interfaces de acuerdo con sus requisitos. Se puede decir que las interfaces son esqueletos implementados por desarrolladores.
A partir de PHP5, es posible definir una interfaz, como esta:
interface Mail {
public function sendMail();
}
Entonces, si otra clase implementó esa interfaz, así:
class Report implements Mail {
// sendMail() Definition goes here
}
Constantes
Una constante es algo así como una variable, ya que tiene un valor, pero en realidad es más como una función porque una constante es inmutable. Una vez que declaras una constante, no cambia.
Declarar una constante es fácil, como se hace en esta versión de MyClass:
class MyClass {
const requiredMargin = 1.7;
function __construct($incomingValue) {
// Statements here run every time
// an instance of the class
// is created.
}
}
En esta clase, requiredMargin es una constante. Se declara con la palabra clave const, y bajo ninguna circunstancia se puede cambiar a otra que no sea 1.7. Tenga en cuenta que el nombre de la constante no tiene un $ al principio, como lo hacen los nombres de las variables.
Clases abstractas
Una clase abstracta es aquella que no se puede instanciar, solo heredar. Declaras una clase abstracta con la palabra claveabstract, así -
Cuando se hereda de una clase abstracta, todos los métodos marcados como abstractos en la declaración de clase del padre deben ser definidos por el hijo; además, estos métodos deben definirse con la misma visibilidad.
abstract class MyAbstractClass {
abstract function myAbstractFunction() {
}
}
Tenga en cuenta que las definiciones de funciones dentro de una clase abstracta también deben estar precedidas por la palabra clave abstract. No es legal tener definiciones de funciones abstractas dentro de una clase no abstracta.
Palabra clave estática
Declarar miembros de clase o métodos como estáticos los hace accesibles sin necesidad de instanciar la clase. No se puede acceder a un miembro declarado como estático con un objeto de clase instanciado (aunque un método estático sí).
Pruebe el siguiente ejemplo:
<?php
class Foo {
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
print Foo::$my_static . "\n";
$foo = new Foo();
print $foo->staticValue() . "\n";
?>
Palabra clave final
PHP 5 introduce la palabra clave final, que evita que las clases secundarias anulen un método prefijando la definición con final. Si la clase en sí se está definiendo como final, no se puede extender.
El siguiente ejemplo da como resultado un error fatal: no se puede anular el método final BaseClass :: moreTesting ()
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called<br>";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called<br>";
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called<br>";
}
}
?>
Llamar a constructores padres
En lugar de escribir un constructor completamente nuevo para la subclase, escribámoslo llamando al constructor del padre explícitamente y luego haciendo lo que sea necesario además para la instanciación de la subclase. Aquí hay un ejemplo simple:
class Name {
var $_firstName;
var $_lastName;
function Name($first_name, $last_name) {
$this->_firstName = $first_name;
$this->_lastName = $last_name;
}
function toString() {
return($this->_lastName .", " .$this->_firstName);
}
}
class NameSub1 extends Name {
var $_middleInitial;
function NameSub1($first_name, $middle_initial, $last_name) {
Name::Name($first_name, $last_name);
$this->_middleInitial = $middle_initial;
}
function toString() {
return(Name::toString() . " " . $this->_middleInitial);
}
}
En este ejemplo, tenemos una clase padre (Nombre), que tiene un constructor de dos argumentos, y una subclase (NameSub1), que tiene un constructor de tres argumentos. El constructor de NameSub1 funciona llamando a su constructor padre explícitamente usando la sintaxis :: (pasando dos de sus argumentos) y luego configurando un campo adicional. De manera similar, NameSub1 define su función no constructora toString () en términos de la función principal que anula.
NOTE- Se puede definir un constructor con el mismo nombre que el de una clase. Se define en el ejemplo anterior.