miércoles, 14 de abril de 2010

Modificadores de Acceso

Modificadores:

Los modificadores son elementos del lenguaje que se colocan delante de la definición de variables locales, dato miembro, métodos o clases y que alteran o condicionan el significado del elemento.

Modificadores de acceso

Uno de los principios de la programación orientada a objetos es la encapsulación, que es un proceso por el que se ocultan las características internas de un objeto a aquellos elementos que no tienen porque conocerla. Los modificadores de acceso sirven para indicar los permisos que tendrán otros objetos para acceder a sus métodos y propiedades.

Los modificadores de acceso permiten al diseñador de una clase determinar quien accede a los datos y métodos miembros de una clase.
Los modificadores de acceso preceden a la declaración de un elemento de la clase (ya sea dato o método), de la siguiente forma:
[modificadores] tipo_variable nombre;
[modificadores] tipo_devuelto nombre_Metodo ( lista_Argumentos );

- Los modificadores de acceso son palabras clave que especifican la accesibilidad declarada de un miembro o un tipo.

- Son palabras clave agregadas a la clase, estructura o declaración de miembro para especificar estas restricciones.

1- Modificador public

Es el nivel de acceso más permisivo. Sirve para indicar que el método o atributo de la clase es público. En este caso se puede acceder a ese atributo, para visualizarlo o editarlo, por cualquier otro elemento de nuestro programa. Es el modificador que se aplica si no se indica otra cosa.

Todo el mundo puede acceder al elemento. Si es un dato miembro, todo el mundo puede ver el elemento, es decir, usarlo y asignarlo. Si es un método todo el mundo puede invocarlo.

Veamos un ejemplo de clase donde hemos declarado como public sus elementos, un método y una propiedad. Se trata de la clase "dado", que tiene un atributo con su puntuación y un método para tirar el dado y obtener una nueva puntuación aleatoria.


class dado{
public $puntos;

function __construct(){
srand((double)microtime()*1000000);
}

public function tirate(){
$this->puntos=$randval = rand(1,6);
}
}

$mi_dado = new dado();

for ($i=0;$i<30;$i++){
$mi_dado->tirate();
echo "
Han salido " . $mi_dado->puntos . " puntos";
}

Vemos la declaración de la clase dado y luego unas líneas de código para ilustrar su funcionamiento. En el ejemplo se realiza un bucle 30 veces, en las cuales se tira el dado y se muestra la puntuación que se ha obtenido.

Como el atributo $puntos y el método tirate() son públicos, se puede acceder a ellos desde fuera del objeto, o lo que es lo mismo, desde fuera del código de la clase.


2 - Modificador Private

Es el nivel de acceso más restrictivo. Sirve para indicar que esa variable sólo se va a poder acceder desde el propio objeto, nunca desde fuera. Si intentamos acceder a un método o atributo declarado private desde fuera del propio objeto, obtendremos un mensaje de error indicando que no es posible a ese elemento.

Sólo se puede acceder al elemento desde métodos de la clase, o sólo puede invocarse el método desde otro método de la clase.

Si en el ejemplo anterior hubiéramos declarado private el método y la propiedad de la clase dado, hubiéramos recibido un mensaje de error.

Aquí tenemos otra posible implementación de la clase dado, declarando como private el atributo puntos y el método tirate().


class dado{
private $puntos;

function __construct(){
srand((double)microtime()*1000000);
}

private function tirate(){
$this->puntos=$randval = rand(1,6);
}

public function dame_nueva_puntuacion(){
$this->tirate();
return $this->puntos;
}
}

$mi_dado = new dado();

for ($i=0;$i<30;$i++){
echo "
Han salido " . $mi_dado->dame_nueva_puntuacion() . " puntos";
}

Hemos tenido que crear un nuevo método público para operar con el dado, porque si es todo privado no hay manera de hacer uso de él. El mencionado método es dame_nueva_puntuación(), que realiza la acción de tirar el dado y devolver el valor que ha salido.

3 - Modificador Protected

Este indica un nivel de acceso medio y un poco más especial que los anteriores. Sirve para que el método o atributo sea público dentro del código de la propia clase y de cualquier clase que herede de aquella donde está el método o propiedad protected. Es privado y no accesible desde cualquier otra parte. Es decir, un elemento protected es público dentro de la propia clase y en sus heredadas.

Más adelante explicaremos la herencia y podremos ofrecer ejemplos con el modificador protected.

Conclusión

Muchas veces el propio desarrollador es el que fija su criterio a la hora de aplicar los distintos modificadores de acceso a atributos y métodos. Poca protección implica que los objetos pierdan su encapsulación y con ello una de las ventajas de la POO. Una protección mayor puede hacer más laborioso de generar el código del programa, pero en general es aconsejable.

LA HERENCIA

La herencia es uno de los mecanismos fundamentales de la programación orientada a objetos. Por medio de la herencia, se pueden definir clases a partir de la declaración de otras clases. Las clases que heredan incluyen tanto los métodos como las propiedades de la clase a partir de la que están definidos.

Por ejemplo, pensemos en la clase "vehículo". Esta clase general puede incluir las características generales de todos los vehículos (atributos de la clase), como la matrícula, año de fabricación y potencia. Además, incluirá algunas funcionalidades (métodos de la clase) como podrían ser, arrancar() o moverse().

Ahora bien, en la práctica existen varios tipos de vehículos, como los coches, los autobuses y los camiones. Todos ellos tienen unas características comunes, que han sido definidas en la clase vehículo. Además, tendrán una serie de características propias del tipo de vehículo, que, en principio, no tienen otros tipos de vehículos. Por ejemplo, los camiones pueden tener una carga máxima permitida o los autobuses un número de plazas disponibles. Del mismo modo, las clases más específicas pueden tener unas funcionalidades propias, como los camiones cargar() y descargar(), o los autobuses aceptar_pasajeros() o vender_billete().

Lo normal en sistemas de herencia es que las clases que heredan de otras incluyan nuevas características y funcionalidades, aparte de los atributos y métodos heredados. Pero esto no es imprescindible, de modo que se pueden crear objetos que hereden de otros y no incluyan nada nuevo.

La programación orientada a objetos nos ofrece una serie de mecanismos para definir este tipo de estructuras, de modo que se puedan crear jerarquías de objetos que heredan unos de otros. Para ello, continuando con nuestro ejemplo de video club, vamos a crear los distintos tipos de elementos que se ofrecen en alquiler.

Como todo el mundo conoce, los videos club ofrecen distintos tipos de elementos para alquiler, como pueden ser las películas (cintas de vídeo o DVD) y los juegos. Cada elemento tiene unas características propias y algunas comunes. Hemos llamado "soporte" a la clase general, que incluye las características comunes para todos los tipos de elementos en alquiler. Luego hemos creado tres tipos de soportes distintos, que heredan de la clase soporte, pero que incluyen algunas características y funcionalidades nuevas. Estos tipos de soporte serán "cinta_video", "dvd" y "juego".

El esquema de herencia que vamos a realizar en este ejemplo se puede ver en la siguiente imagen.


Empezamos por la clase soporte. Su código será el siguiente:

class soporte{
public $titulo;
protected $numero;
private $precio;

function __construct($tit,$num,$precio){
$this->titulo = $tit;
$this->numero = $num;
$this->precio = $precio;
}

public function dame_precio_sin_iva(){
return $this->precio;
}

public function dame_precio_con_iva(){
return $this->precio * 1.16;
}

public function dame_numero_identificacion(){
return $this->numero;
}

public function imprime_caracteristicas(){
echo $this->titulo;
echo "
" . $this->precio . " (IVA no incluido)";
}
}

Los atributos que hemos definido son, título, numero (un identificador del soporte) y precio. Hemos aplicado a cada uno un modificador de acceso distinto, para poder practicar los distintos tipos de acceso.

Hemos definido un constructor, que recibe los valores para la inicialización del objeto. Un método dame_precio_sin_iva(), que devuelve el precio del soporte, sin aplicarle el IVA. Otro método dame_precio_con_iva(), que devuelve el precio una vez aplicado el 16% de IVA. El método dame_numero_identificacion(), que devuelve el número de identificador y imprime_caracteristicas(), que muestra en la página las características de este soporte.

Nota: Como se ha definido como private el atributo precio, este atributo sólo se podrá acceder dentro del código de la clase, es decir, en la propia definición del objeto. Si queremos acceder al precio desde fuera de la clase (algo muy normal si tenemos en cuenta que vamos a necesitar el precio de un soporte desde otras partes de la aplicación) será necesario crear un método que nos devuelva el valor del precio. Este método debería definirse como public, para que se pueda acceder desde cualquier sitio que se necesite.

En todos los métodos se hace uso de la variable $this. Esta variable no es más que una referencia al objeto sobre el que se está ejecutando el método. En programación orientada a objetos, para ejecutar cualquiera de estos métodos, primero tenemos que haber creado un objeto a partir de una clase. Luego podremos llamar los métodos de un objeto. Esto se hace con $mi_objeto->metodo_a_llamar(). Dentro de método, cuando se utiliza la variable $this, se está haciendo referencia al objeto sobre el que se ha llamado al método, en este caso, el objeto $mi_objeto. Con $this->titulo estamos haciendo referencia al atributo "titulo" que tiene el objeto $mi_objeto.


Si queremos probar la clase soporte, para confirmar que se ejecuta correctamente y que ofrece resultados coherentes, podemos utilizar un código como el siguiente.
$soporte1 = new soporte("Los Intocables",22,3);
echo "" . $soporte1->titulo . "";
echo "
Precio: " . $soporte1->dame_precio_sin_iva() . " euros";
echo "
Precio IVA incluido: " . $soporte1->dame_precio_con_iva() . " euros";

En este caso hemos creado una instancia de la clase soporte, en un objeto que hemos llamado $soporte1. Luego imprimimos su atributo titulo (como el título ha sido definido como public, podemos acceder a él desde fuera del código de la clase.
Luego se llaman a los métodos dame_precio_sin_iva() y dame_precio_con_iva() para el objeto creado.

Nos daría como resultado esto:
Los Intocables Precio: 3 euros
Precio IVA incluido: 3.48 euros

No hay comentarios:

Publicar un comentario