que-es-una-clase-sellada-en-programacion

Qué son y cómo usar las clases selladas

Las clases selladas, o finales, son clases que no pueden ser heredadas por otras clases, asegurando que ciertas clases no sean extendidas o modificadas.

Te preguntarás ¿Por qué querría yo impedir la herencia? ¿No va un poco en contra de los principios de diseño de la programación orientada a objetos?

El principal motivo es por seguridad. Declarar una clase como sellada sirve para proteger el diseño del software, ante una modificación no deseada de una clase.

clase-sellada

Tu clase sellada y cerrada para siempre

Esto es particularmente útil en frameworks y librerías, donde el desarrollador del framework quiere evitar que los usuarios modifiquen componentes críticos.

Por ejemplo, imagina que yo genero una librería para un proyecto, que gestiona los pagos de unos clientes. Para lo cuál tengo mis objetos, todo monos, muy bien hechos.

Si otra persona coge una de mis clases, la hereda, modifica su comportamiento, y la devuelve a la librería, el resto de objetos se la van a “tragar”. Porque así funciona el Polimorfismo.

Como es un proceso importante o crítico y no quiero que, por error o intencionadamente, alguien modifique su comportamiento marcaré las clases importantes como selladas.

Ejemplos en distintos lenguajes

El tema de clases selladas o finales es de los que menos estandarizado está entre los distintos lenguajes de programación, y cada uno lo hace según su propia aproximación.

Los lenguajes más orientados a objetos, como C++, C# o Java lo tienen de forma nativa, para lo cual emplean una palabra reservada.

Otros lenguajes como Kotlin tienen todos los métodos sellados por defecto, y hay que abrirlos explícitamente con la palabra reservada Open.

Mientras que los lenguajes de tipado dinámico, como JavaScript o Python, por su propia implementación son los que más sufren a la hora de recoger el concepto.

Veámoslo con algunos ejemplos

En C#, una clase sellada se declara utilizando la palabra clave sealed.

public sealed class Utilidades
{
    public void MetodoUtil()
    {
        Console.WriteLine("Método de utilidad");
    }
}

// Esto generará un error de compilación
public class SubUtilidades : Utilidades
{
}

En C++, las clases selladas se pueden lograr utilizando la palabra clave final.

class Utilidades final
{
public:
    void MetodoUtil() const {
        std::cout << "Método de utilidad" << std::endl;
    }
};

// Esto generará un error de compilación
class SubUtilidades : public Utilidades
{
};

En TypeScript, se puede simular el comportamiento de una clase sellada utilizando constructores privados.

class Utilidades {
    private constructor() {}

    static metodoUtil(): void {
        console.log("Método de utilidad");
    }
}

// Esto generará un error de compilación
class SubUtilidades extends Utilidades {
}

En Python, las clases selladas no son soportadas directamente, pero se puede simular su comportamiento utilizando metaclases.

class FinalMeta(type):
    def __new__(cls, name, bases, dct):
        if any(isinstance(base, FinalMeta) for base in bases):
            raise TypeError(f"Cannot inherit from final class {bases}")
        return super().__new__(cls, name, bases, dct)

class Utilidades(metaclass=FinalMeta):
    def metodo_util(self):
        print("Método de utilidad")

# Esto generará un error en tiempo de ejecución
class SubUtilidades(Utilidades):
    pass