Una clase sellada es una clase que no puede tener clases hijas, y para
definirla basta anteponer el modificador sealed a
la definición de una clase normal. Por ejemplo:
sealed class ClaseSellada
{
}
Una utilidad de definir una clase
como sellada es que permite que las llamadas a sus métodos virtuales heredados
se realicen tan eficientemente como si fuesen no virtuales, pues al no poder
existir clases hijas que los redefinan no puede haber polimorfismo y no hay que
determinar cuál es la versión correcta del método a la que se ha de llamar. Nótese que se ha dicho métodos virtuales
heredados, pues lo que no se permite es definir miembros virtuales dentrode
este tipo de clases, ya que al no poderse heredarse de ellas es algo sin
sentido en tanto que nunca podráin redefinirse.
Ahora bien, hay que tener en cuenta
que sellar reduce enormemente su capacidad de reutilización, y eso es algo que
el aumento de eficiencia obtenido en las llamadas a sus métodos virtuales no
suele compensar. En realidad la principal causa de la inclusión de estas clases
en C# es que permiten asegurar que ciertas clases críticas nunca podrán tener
clases hijas. Por ejemplo, para simplificar el funcionamiento del CLR y los
compiladores se ha optado porque todos los tipos de datos básicos excepto System.Object
estén sellados, pues así las operaciones con ellos siempre se realizarán de la
misma forma al no influirles el polimorfismo.
Téngase en cuenta que es absurdo
definir simultánemanente una clase como abstract y sealed,
pues nunca podría accederse a la misma al no poderse crear clases hijas suyas
que definan sus métodos abstractos. Por esta razón, el compilador considera
erróneo definir una clase con ambos modificadores a la vez.
Aparte de para sellar clases,
también se puede usar sealed como
modificador en la redefinición de un método para conseguir que la nueva versión
del mismo que se defina deje de ser virtual y se le puedan aplicar las
optimizaciones arriba comentadas. Un ejemplo de esto es el siguiente:
class A
{
public abstract F();
}
class B:A
{
public sealed
override F() // F() deja de ser redefinible
{}
}