"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Composition vs Inheritance

Composition vs Inheritance

Published on 2024-11-09
Browse:263

Composición vs Herencia

Introduction

Inheritance and composition are two fundamental concepts in object-oriented programming (OOP), but they are used differently and have different purposes. The objective of this post is to review those purposes, and some things to keep in mind when choosing them.

Concepts of inheritance

When we think about applying inheritance in our designs, we have to understand:

  • Definition: In inheritance, a class (called a derived class or subclass) can inherit properties and behaviors from another class (called a base class or superclass). The derived class can extend or modify the functionality of the base class.
  • Relationship: It is a relationship "is a" (is-a). For example, if you have a class "Vehicle" and another class "Car", the class "Car" is a subclass of "Vehicle".
  • Advantages: Promotes code reuse and allows easy extension of functionality.

Composition concepts

On the other hand, if we think about composing objects together:

  • Definition: In composition, an object contains other objects and delegates part of its functionality to them. Instead of inheritance, a class uses instances of other classes to achieve its functionality.
  • Relationship: It is a "has-a" relationship. For example, if you have a class "Engine" and a class "Car", the class "Car" can have an object of class "Engine".
  • Advantages: Greater flexibility and less coupling between classes. Changes in one class do not directly affect the other.

Why composition on inheritance?

The question of whether composition is better than inheritance or vice versa is a debated topic in software design. Both approaches have their advantages and disadvantages, and the choice depends on the specific project context and requirements. Here I will present you with an example where composition can be preferable to inheritance.

Let's explore an example in Java that illustrates how composition can be preferable to inheritance in certain cases. Suppose we are working on an order processing system in an online store.

  • Inheritance Approach:

First, let's consider an approach using inheritance to represent different types of purchasable products, such as books and electronics:

// Clase base para productos
class Producto {
    String nombre;
    double precio;

    Producto(String nombre, double precio) {
        this.nombre = nombre;
        this.precio = precio;
    }

    void procesarPedido() {
        System.out.println("Procesando pedido para "   nombre);
    }
}

// Clase para productos electrónicos que hereda de Producto
class ProductoElectronico extends Producto {
    String modelo;

    ProductoElectronico(String nombre, double precio, String modelo) {
        super(nombre, precio);
        this.modelo = modelo;
    }
}

// Clase para libros que hereda de Producto
class Libro extends Producto {
    String autor;

    Libro(String nombre, double precio, String autor) {
        super(nombre, precio);
        this.autor = autor;
    }
}

This approach works, but what if you need to introduce new product types or add specific functionality for certain product types?

  • Focus with Composition:

Instead of relying entirely on inheritance, we could use composition to handle different types of products more flexibly:

// Clase para productos
class Producto {
    String nombre;
    double precio;

    Producto(String nombre, double precio) {
        this.nombre = nombre;
        this.precio = precio;
    }

    void procesarPedido() {
        System.out.println("Procesando pedido para "   nombre);
    }
}

// Clase para productos electrónicos que utiliza composición
class ProductoElectronico {
    Producto producto;
    String modelo;

    ProductoElectronico(String nombre, double precio, String modelo) {
        this.producto = new Producto(nombre, precio);
        this.modelo = modelo;
    }

    // Puedes agregar lógica específica para productos electrónicos si es necesario
    void procesarPedidoEspecifico() {
        System.out.println("Procesando pedido específico para "   producto.nombre);
    }
}

// Clase para libros que utiliza composición
class Libro {
    Producto producto;
    String autor;

    Libro(String nombre, double precio, String autor) {
        this.producto = new Producto(nombre, precio);
        this.autor = autor;
    }

    // Puedes agregar lógica específica para libros si es necesario
    void procesarPedidoEspecifico() {
        System.out.println("Procesando pedido específico para "   producto.nombre);
    }
}

In this approach, each product type has an instance of the Product class, allowing common logic to be shared for processing orders. Additionally, each product type can have its own specific logic using methods such as processSpecificOrder(). This design is more flexible and makes it easier to introduce new product types or modify type-specific logic without affecting the inheritance hierarchy.

When to apply inheritance?

While the choice between inheritance and composition in software design depends on the context and specific requirements of the problem you are addressing. Here are some situations where you might consider inheritance as a more appropriate option than composition:

  • "is-a" relationship: Inheritance is especially appropriate when there is a clear "is-a" relationship between classes. If a class B is a more specific or specialized version of a class A, then inheritance makes sense. For example, if you have a Vehicle class and a Car class, the "is-a" relationship is clear, since a car is a type of vehicle.
class Vehiculo {
    // ...
}

class Automovil extends Vehiculo {
    // ...
}
  • Code reuse: Inheritance allows code reuse, since the derived class inherits the members and methods of the base class. This can be beneficial when there is a significant amount of common code between related classes.
class Animal {
    void comer() {
        // Lógica común para comer
    }
}

class Perro extends Animal {
    void ladrar() {
        // Lógica específica para ladrar
    }
}
  • Polymorphism: Inheritance is fundamental to the implementation of polymorphism, which allows derived classes to provide specific implementations of methods inherited from the base class. This is useful in scenarios where you need to treat objects of derived classes uniformly.
class Figura {
    void dibujar() {
        // Lógica común para dibujar una figura
    }
}

class Circulo extends Figura {
    void dibujar() {
        // Lógica específica para dibujar un círculo
    }
}

class Cuadrado extends Figura {
    void dibujar() {
        // Lógica específica para dibujar un cuadrado
    }
}

  • Functionality Extensions: If you are extending or specializing existing functionality, inheritance may be more natural. For example, if you are developing a library and you provide a base class with basic functionality, users of your library can derive from that base class to extend that functionality.

What happens if we make a bad inheritance?

If we continue to evaluate the pros and cons of inheritance, one of the problems that can arise from bad inheritance is that we would violate the Interface Segregation Principle, which states that clients should not be forced to depend on interfaces that they do not use. If an interface is extended in a way that includes methods that are not relevant to all implementations, clients using that interface could be forced to implement or depend on methods they do not need, which can lead to a less clean and more difficult design. to maintain.

Conclusion

In summary, inheritance focuses on the "is a" relationship and is used to model class hierarchies, while composition focuses on the "has a" relationship and is used to construct complex objects from others. simpler objects. Both approaches have their specific use cases and are chosen based on the structure and nature of the relationships in the software design.

Release Statement This article is reproduced at: https://dev.to/rlgino/composicion-vs-herencia-4664?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3