Saltar a contenido

Relaciones entre Clases

Tipos de relaciones

  • Composición
  • Agregación
  • Asociación
  • Dependencia
  • Herencia

Composición

Las clases se pueden componer unas con otras:

# Clase interior
class Interna:
    def __init__(self):
        self.valor = 0

    def metodo(self):
        print(f"Valor interno: {self.valor}")

# Clase exterior
class Compuesta:
    def __init__(self):
        self.interno = Interna()

En este caso las dos clases se instancian juntas creando sus respectivos objetos, pero uno de estos objetos queda contenido adentro del otro.

instancia = Compuesta()           # creación objeto compuesto
instancia.interno.valor = 15       # acceso a atributos internos 
instancia.interno.metodo()         # acceso a métodos internos
# instancia.metodo()              # da ERROR

Una desventaja de la composición es la eliminación del objeto interno si el objeto externo se elimina.

La composición se representa en los diagramas UML con una línea terminada en un rombo lleno que apunta a la clase compuesta:

---
title: UML - Composición
---
classDiagram
    Interna --* Compuesta : composicion
```mermaid
---
title: UML - Composición
---
classDiagram
    Interna --* Compuesta : composicion
```

Agregado ("agregacion")

Esta opción es una alternativa a la composición. Esta consiste en crear la instancia de la clase interna primero y luego pasarla como argumento para crear la clase exterior:

# clase interior
class Interna:
    def __init__(self):
        self.valor = 0

    def metodo(self):
        print(f"Valor interno: {self.valor}")

# clase exterior
class Agregada:
    def __init__(self, referencia):
        self.objeto = referencia

# objeto de la clase interna
instancia_interna = Interna()   
# clase interna como argumento para la otra
instancia_agregada = Agregada(instancia_interna)
# acceso a atributos y métodos
instancia_agregada.objeto.valor = 15        
instancia_agregada.objeto.metodo()

De esta manera los dos objetos tienen existencia independiente el uno del otro: si uno es eliminado, el otro seguirá existiendo.

En el diagrama UML, la agregación se representa con una línea terminada en un rombo vacío que apunta a la clase exterior:

---
title: UML - Agregado
---
classDiagram
    Interna --o Agregada : agregacion
```mermaid
---
title: UML - Agregado
---
classDiagram
    Interna --o Agregada : agregacion
```

Dependencia

Hay una relación de dependencia cuando una clase depende de otra para poder funcionar.

La dependencia se representa en UML como una flecha fina que apunta de la clase dependiente a la clase requerida:

---
title: UML - Dependencia
---
classDiagram
    Dependiente --> Requerida : dependencia
```mermaid
---
title: UML - Dependencia
---
classDiagram
    Dependiente --> Requerida : dependencia
```

Asociación

La asociación es una relación semántica entre dos clases. Las clases están vinculadas entre sí pero no hay una jerarquía entre ellas.

La asociación se representa con una línea simple.

---
title: UML - Asociación
---
classDiagram
    Clase 1 -- Clase 2 : asociación
```mermaid
---
title: UML - Asociación
---
classDiagram
    Clase 1 -- Clase 2 : asociación
```

Herencia

La herencia es una relación jerárquica donde una clase (superclase) sirve de referencia a la otra (subclase), heredándole sus atributos y sus métodos.

Es la relación que habilita las propiedades de herencia y polimorfismo explicadas en el capítulo de POO.

Se representa con una flecha vacía apuntando a la clase de mayor jerarquía, es decir la superclase.

---
title: UML - Herencia
---
classDiagram
    SuperClase <|-- SubClase : herencia
```mermaid
---
title: UML - Herencia
---
classDiagram
    SuperClase <|-- SubClase : herencia
```

Referencias

Stack Overflow - What's the pythonic way to use getters and setters

HecktorProfe - Herencia múltiple

BarcelonaGeeks - Agregación y Composición

DiagramasUML - Diagrama de clases