Contexto


¿Te gusta ser eficiente en todo lo que haces? ¡Usa clases en tu código!

Trabajar con clases en PHP es una gran manera de agilizar tu código. Las clases a veces son vistas como algo demasiado complicado, pero en realidad son fáciles de usar una vez que comprendes los diferentes niveles de privacidad, extensiones y demás. En el presente tema verás cómo utilizarlas.

Explicación


5.1 Objetos en PHP

Las últimas versiones de PHP ya se consideran un lenguaje de Programación Orientado a Objetos (OOP), lo que significa que debes aprender a programar de una manera especial, casi como se haría con objetos en la vida real. En OOP se trabaja en función de objetos, sus propiedades y sus métodos. Para entender esto, toma como ejemplo un automóvil. Supón que deseas programarlo con OOP, por lo tanto podrías fragmentarlo de esta manera:

  • El objeto es el automóvil en sí, todas las partes que lo conforman.
  • Las características como el color, la marca, entre otras, serían  sus propiedades.
  • Los métodos serían entonces las funcionalidades, como arrancar, detenerse, girar, etcétera.

Ahora bien, las clases son la encapsulación o definición de todos estos elementos en documentos que podemos reutilizar, heredar y modificar en algunos aspectos de manera dinámica. Cuando programamos un objeto y definimos sus características y funcionalidades en realidad lo que estamos haciendo es programar una clase. Cada nuevo objeto creado por medio de estas clases son en realidad instancias de las mismas.

Las propiedades o atributos en las clases son las características de los objetos, son variables en las que se almacenan datos relacionados con los objetos. Cuando definimos una propiedad normalmente especificamos su nombre y su tipo.

Por otro lado, los métodos en las clases son las funcionalidades asociadas a los objetos. Cuando estamos programando las clases las llamamos métodos.



En ocasiones necesitarás una clase parecida a una que ya tienes. Ojo, parecida, pero no la misma. Lo que puedes hacer para trabajar eficientemente es crear una nueva clase que herede (inheritance) las características de la original, pero con las modificaciones que se requieren. En ese momento, la clase original es llamada superclase (superclass) y la nueva es llamada subclase (subclass).

Haz clic en el botón para acceder a la práctica.

5.2 Declarando una clase

El nombre de una clase es sensible a mayúsculas y minúsculas, Por regla general se nombra con mayúscula al principio. Observa el siguiente ejemplo:

<?php
  class SimpleClass { // declaramos la clase
      public $var = 'valor predeterminado'; // declaramos algunas propiedades
      public function displayVar() { // declaramos un metodo
          echo $this->var;
      }
  }
?>

Como puedes ver, la estructura de una clase es bastante simple. Después de declarar la clase con la palabra clave class, le damos un nombre siguiendo las reglas que hemos mencionado antes y empezando su nombre con mayúscula. Las llaves { } contienen toda la información de la clase.

En el ejemplo se declararon propiedades que serán utilizadas en los métodos posteriores. El siguiente paso es escribir los métodos que darán funcionalidad a esta clase. Algo nuevo que puedes observar es el uso de la pseudovariable $this. Este tipo de variable sirve como referencia al objeto donde estamos ejecutando el código, en otras palabras, indica que estamos hablando de un objeto que existe en la clase donde lo estamos invocando.

Veamos este nuevo ejemplo:

<?php
  $object = new User; //creamos una instancia de User dentro de una variable
  print_r($object); // esto es nuevo!...fijate en la explicacion!
  class User { //declaramos la clase, su nombre empieza con mayusculas
 	public $name, $password; //algunas variables
 	function save_user() { //creamos el metodo save_user
        echo "Aqui iria mas codigo"; //un echo regular
 	}
  }
?>

Este ejemplo arroja algunas novedades. En primer lugar, la creación de una instancia de la clase User. En este caso, la palabra clave new genera una copia de la clase User con toda la funcionalidad de la original.

El comando print_r($object) le indica a PHP que entregue información en formato legible para seres humanos. La _r significa literalmente in human-readable format. Si no has ejecutado el programa hazlo para que veas a lo que nos referimos. Prueba colocando solamente print para que notes la diferencia.

Modifiquemos ahora el ejemplo anterior con la finalidad de acceder a las propiedades del objeto para pasar algunos valores. Esto quedaría así:

<?php
$object = new User; //nuevo objeto creado
  $object->name = "Juan"; //accedemos al objeto y le asignamos un valor
  $object->password = "juan_password"; 
  $object->save_user(); //ejecucion del metodo save_user()
  print_r($object); //ya vimos de que se trata esto ;)
  class User {
 	public $name, $password; // recuerdas el keyword public?
 	function save_user() {
        //echo "Aqui iria mas codigo"; Este tambien lo comentamos
 	}
  }
?>

Observa el nuevo código. La parte importante es cómo accedemos a las propiedades del  objeto, en este caso las variables $namey $password para asignarles los valores que necesitamos. Utilizamos el operador -> para acceder a las propiedades del nuevo objeto, pon especial atención que aunque las propiedades son variables, al momento de acceder a ellas con dicho operados, no usamos el signo de $.

Si no lo has hecho ya, ejecuta el programa y observa los resultados.

Haz clic en el botón para acceder a la práctica.

5.3 Métodos estáticos

Podemos definir métodos estáticos dentro de una clase. Estos métodos se caracterizan porque sólo son ejecutados dentro de una clase y no sobre el objeto. Un método estático no puede acceder a las características del objeto. Tales métodos son útiles para realizar acciones relacionadas con la propia clase, pero no a casos específicos de la misma.

Observa estos ejemplos:

<?php
  User::pwd_string(); //se llama al metodo
  class User {
 	static function pwd_string() { //se define la funcion con static
       echo "Falta tu contraseña!";
 	}
  }
?>

Nota cómo llamamos la clase en sí, junto con el método estático, utilizando : :, también conocido como el operador de resolución de alcance, no utilizamos ->.

Veamos un ejemplo más práctico:

<?php
Idioma::lookup(); //llamamos al metodo estatico
  class Idioma {
  	const ENGLISH = 0; //recuerdas las constantes?
  	const SPANISH = 1;
  	const FRENCH = 2;
  	const GERMAN = 3;
	// ...
   	static function lookup() { //nuestro metodo estatico
       	echo self::SPANISH; //esto es nuevo!
					 //mira mas abajo para una explicacion!
   	}
  }
?>

El ejemplo anterior muestra un pseudoprograma que valida el idioma en que se presenta alguna información. Un programa de este tipo podría servir para cambiar el idioma del contenido de una página web de acuerdo a la selección por parte del usuario.

Puedes hacer referencia a constantes directamente, usando la palabra clave self y el operador : :. Toma en cuenta que este código llama a la clase directamente, usando el operador : : en la primer línea, sin crear una instancia de ella primero. Como puedes observar, el valor que regresa cuando se ejecuta este código es 1.

Recuerda que una vez que se define una constante, no es posible cambiar su valor.

Public

Estas propiedades pueden ser vistas desde cualquier punto del código y son las más comunes de usar. Los métodos se supone que sean públicos por defecto.

Utiliza public cuando algún código externo necesite acceder a estas variables o métodos y que además las clases que se extiendan también necesiten heredarlos.

Protected

Estas propiedades y métodos pueden ser referenciados únicamente por métodos de la clase del objeto y por aquellos de cualquier subclase.

Usa protected cuando el código exterior no necesita acceder a estos miembros, pero las clases que se extienden de ellas deban heredarlos.

Private

Estos solamente pueden referenciarse únicamente por métodos dentro de la misma clase y no por las subclases.

Coloca las variables o métodos como private cuando el código externo no necesita acceder a esta información y cuando las clases que se extienden tampoco los necesiten.
Cuando están como private serán invisibles para los demás.

Herencia (Inheritance)

Bueno, ya escribimos una clase… ¿y ahora qué?

Una de las propiedades que tienen las clases es la herencia, que implica tomar una clase y convertirla en una o varias subclases. Dicha propiedad puede evitar que volvamos a escribir muchas líneas de código.Es posible tomar una clase similar a la que necesitamos escribir o que contiene variables o propiedades que necesitamos, extenderla a una subclase y terminar de modificar las partes que son diferentes. Esto se consigue mediante el keyword extends.

<?php
  //ya sabemos que es esto! :)
  $object = new Suscriptor; //recuerdas como crear objetos?
  $object->name = "Alfredo"; //y como acceder a las propiedades del objeto?
  $object->password = "pword"; //y asignarle valores?
  $object->phone = "012 345 6789";
  $object->email = "alfredo@dominio.com";
  $object->display(); //y como acceder a un metodo de un objeto tambien?
  class Usuario{ //la clase usuario
     public $name, $password; //las propiedades del objeto Usuario
     function saver_usuario() { //un metodo de Usuario
        echo "Aqui va el código de Usuario\n";
     }
  }
  class Suscriptor extends Usuario{ //extendemos Usuario
     public $phone, $email; //propiedades de la subclase Suscriptor
     function display() { //el metodo de Suscriptor
        echo "Nombre: " . $this->name . "\n"; // recuerdas el uso de \n ?
        echo "Contraseña: " . $this->password . "\n"; // y de $this ?
        echo "Telefono: " . $this->phone . "\n";
        echo "E-mail: " . $this->email;
     }
  }
?>

Observa este ejemplo donde a partir de la clase Suscriptor se declara una subclase usuario por medio de extends:

Analiza el ejemplo anterior. Observa cómo estamos usando la clase User para tomar las propiedades que necesitamos al escribir la subclase Suscriptor. En la clase Usuario sólo teníamos las variables $name y $password, además del método saver_usuario() que puede tener la funcionalidad que deseemos darle.

En la subclase Suscriptor, además de las variables $name y $password, necesitamos $phone y $email. Al extender la clase Usuario ya no tenemos que colocar de nuevo las variables que ya están declaradas, sólo tenemos que incorporar las nuevas variables que necesitamos para que nuestro programa funcione correctamente.

¿Comprendes ahora el concepto de extender las clases y de la herencia que usan las subclases?

Parent

Cuando escribimos un método dentro de una subclase, es decir la clase hijo, con el mismo nombre de la clase original, conocido como clase padre, los enunciados sobreescriben a los del método original. En ocasiones este comportamiento no es el que quieres ejecutar, lo que necesitas es que se ejecute el método original. Para lograr este objetivo utilizamos el keyword parent, el cual asegura que el método ejecutado sea el de la clase original.

Escribe y ejecuta este ejemplo:

<?php
$object = new MiSubclase;
$object->test();
$object->test2();

 class ClaseOriginal {
	function test() {
   	echo "[Clase Original] Soy la clase original!\n";
	}
 }
 class MiSubclase extends ClaseOriginal { //recuerdas extends?
	function test() {
   	echo "[Clase MiSublclase] Soy la ejecucion de la subclase!\n";
 }
 function test2() {
	parent::test(); //aqui tenemos la referencia a parent
			   //recuerdas que es esto ::?
 }
}
?>

El resultado debería de ser algo como esto:

[Clase MiSublclase] Soy la ejecucion de la subclase!
[Clase Original] Soy la clase original!

En el enunciado parent: :test(); lo que hacemos es asegurarnos de llamar al método de la clase en la que estamos actuado, en caso de que no lo recuerdes.

Los siguientes ejercicios son muy básicos, pero sirven para que veas los usos que le puedes dar a una clase. Estúdialos, escríbelos y ejecútalos. Luego modifícalos para que hagan algo más.

Haz clic en el botón para acceder a la práctica.

Cierre


Ahora ya tienes un concepto más claro de lo que significa la programación orientada a objetos, pero si todavía te restan algunas dudas, puedes consultar el siguiente video:

Además de ahondar en OOP, en el tema también pudiste ver qué es un objeto y cómo crearlo, además de aprender sobre la utilidad y estructura de una clase. Dentro de esta misma línea pudiste trabajar con los métodos, sus distintas variaciones y con el concepto de herencia.

Cada tema la complejidad aumenta, ¡no olvides experimentar con lo que has aprendido hasta este momento!

Checkpoint


Asegúrate de poder:

  • Utilizar clases con una estructura adecuada.
  • Aplicar los métodos, sus variaciones y el concepto de herencia.
  • Comprender el scope de las variables y su uso.

Referencias


Nixon, R. (2014). Learning PHP, MySQL & JavaScript With jQuery, CSS & HTML5. EE. UU.: O’Reilly Media.