EDIT: Eu acredito que as classes devem ser projetadas para serem abertas. Com algumas restrições, mas não deve ser fechado para herança.
Por quê:
"Aulas finais" ou "aulas seladas" me parecem estranhas. Eu nunca tenho que marcar uma das minhas aulas como "final" ("selado"), porque eu posso ter que herdar essas classes, mais tarde.
Eu tenho comprado / baixado bibliotecas de terceiros com classes, (a maioria dos controles visuais), e realmente grato nenhuma dessas bibliotecas usou "final", mesmo se suportado pela linguagem de programação, onde eles foram codificados, porque acabei de estender essas classes, mesmo que eu tenha compilado bibliotecas sem o código fonte.
Às vezes, eu tenho que lidar com algumas classes "fechadas" ocasionais, e acabei criando uma nova classe "wrapper" contendo a classe dada, que tem membros similares.
class MyBaseWrapper {
protected FinalClass _FinalObject;
public virtual DoSomething()
{
// these method cannot be overriden,
// its from a "final" class
// the wrapper method can be open and virtual:
FinalObject.DoSomething();
}
} // class MyBaseWrapper
class MyBaseWrapper: MyBaseWrapper {
public override DoSomething()
{
// the wrapper method allows "overriding",
// a method from a "final" class:
DoSomethingNewBefore();
FinalObject.DoSomething();
DoSomethingNewAfter();
}
} // class MyBaseWrapper
Os clasificadores de escopo permitem "selar" alguns recursos sem restringir a herança.
Quando eu mudei de Progr. Estruturado. para OOP, comecei a usar membros da classe private , mas, depois de muitos projetos, acabei usando protected e, eventualmente, promovi essas propriedades ou métodos para public , se necessário.
P.S. Eu não gosto de "final" como palavra-chave em C #, prefiro usar "selado" como Java, ou "estéril", seguindo a metáfora de herança. Além disso, "final" é uma palavra ambígua usada em vários contextos.