Existen distindos tipos de relaciones entre clases, entre ellas tenemos:

  • Asociación (conexión entre clases)
  • Dependencia (relación de uso)
  • Generalización/especialización (relaciones de herencia)

Asociación

Una asociación es una relación estructural que describe una conexión entre objetos.

asociacion

Figura 1. Asociación

En la figura 1 podemos observar una relación entre la clase Cliente y la clase Dirección. Aunque no sabemos con detalle que tipo de relación si sabemos que tienen una conexión. Este caso es una asociación bidireccional.

Podemos realizar un relación unidireccional como no los indica la Figura 2. Esta nos indica que la clase Cuenta tiene una relación con la clase Dinero.

asociacion2.PNG

Figura 2. Asociación Directa

Claro que esta puede simplificarse graficamente en UML como:

asociacion3

Figura 3.

La versión en código PHP sería:

<?php

class Cuenta {
    private $balance;

    public function __construct() {
        $balance = new Dinero();
    }

    public function ingresar() {
    }

    public function retirar() {
    }
}

class Dinero {

}

En php los objetos se instancian en el constructor o en otra función, pero no donde se declaran.

Multiplicidad

Determina cuántos objetos de cada tipo intervienen en la relación. Cada asociación tiene dos multiplicidades, una para cada extremo de la relación y se indica la multiplicidad mínima y máxima. En la tabla se presentan todos los tipos de multiplicidad:

Multiplicidad Significado
1 Uno y sólo uno
0 .. 1 Cero o uno
* Cero o varios
0 .. * Cero o varios
1 .. * Uno o varios (al menos uno)

Cuando la multiplicidad mínima es 0, la relación es opcional y si es mayor o igual que 1 establece una relación obligatoria.

asociacion4.PNG

Figura 4. Todo profesor pertenece a un departamento. Un departamento puede pertenecer varios profesores

asociacion5.PNG

Figura 5. Relación opcional y obligaroria.

En la figura 5 se aprecia que un cliente puede o no ser titular de una cuenta (relación opcional) y una cuena ha de tener un titular como mínimo (relación obligatoria).

Existen 2 tipos de asociación llamadas agregación y composición que pueden consultarse en la anterior entrada de este blog.

Dependencia

Es una relación más débil que una asociación que muestra la relación entre un cliente y el proveedor de un servicio usado por el cliente. Los conceptos que hacen parte una relación de dependencia son Cliente y Servidor.

  • Cliente: Es el objeto que solicita un servicio.
  • Servidor: Es el objeto que provee el servicio.
dependencia.PNG

Figura 6. Dependencia

dependencia2.PNG

Figura 7. Dependencia

En la figura 7 podemos obervar que la clase Ecuación necesita las operaciones de la clase Math para poder operar. Este tipo de relación es muy importante porque muchos patrones de diseño usan este tipo de relación.

Generalización / Especialización

Son relaciones de herencia entre una superclase y sus subclases. Podemos usarlas cuando objetos de distintas clases pueden tener atributos similares y exhibir comportamientos parecidos (animales, mamíferos..)

generalizacion.PNG

Figura 8. Generalización

Las subclases heredan características de las clases de las que se derivan y añaden características específicas que las diferencian. En la figura 8 observamos que las subclases Coche y Moto heredan de Vehiculo Terreste, es decir que las características de Vehículo Terreste las obtienen las clases Coche y Moto. Pero no tienen las características de Vehículo aéreo por que no heredan de esa clase.

Representamos el siguiente diagrama en PHP:

generalizacion2.PNG

Figura 9. Ejemplo Generalización

Comenzemos con la superclase Person:

class Person{
    public $name;
    protected $age;
    private $phone;

    public function talk(){
        echo "Talking... ";
    }

    public function setAge($age){
        $this->age = $age;
    }

    protected function walk(){
        echo "Walking...";
    }

}

Vemos que tiene 3 atributos. La variable $phone es privado, es decir que ni las clases heredadas tiene acceso a este atributo. La variable $name es público, tiene acceso en la instancia. La variable $age es protegida, solo tiene acceso la propia clase y sus subclases.

class Employee extends Person {

    public function myAge(){
        echo "My age is " . $this->age;
    }
}

La subclase Employee que hereda de la clase Person tiene un método que utiliza el atributo protegido $age. Puede usarse sin ningún problema. Habría un error si llamara el atributo $phone, el cual es privado y solo puede ser accedida por la clase Person y no sus subclases.

Instanciemos algunos objetos:

$tom = new Employee();

$tom->name = "Tom";

$tom->setAge(30);

$tom->myAge();
  1. Se instancia el objeto $tom con la clase Employee.
  2. Le asignamos a la variable $name el nombre. Funciona perfectamente porque este atributo es público.
  3. Establecemos el atributo $age por medio del método de Employee setAge(). Funciona perfectamente también debido a que el atributo es protegido y puede ser utilizado en los métodos de la subclase.
  4. Imprimimos el atributo de $age que está en Person por medio de un método de Employee myAge().

El siguiente código sería un ejemplo de como NO funcionaría:

$tom = new Employee();

$tom->phone = 313122112;

$tom->walk();

echo $tom->age;
  1. Instancia el objeto con la clase Employee
  2. Intenta asignar un atributo privado, esta line será un error porque el objeto no tiene permiso para asignar este atributo.
  3. El objeto intenta usar un método protedigo. Es un error porque este método solo puede ser accedido por las subclases de Person.
  4. Intenta imprimir un atributo protegido. Es un error porque este atributo solo puede ser accedido por las subclases de Person.