In a big project I work for, I am considering recommending other programmers to always seal their classes if they haven’t considered how their classes should be subclassed. Often times, less-experienced programmers never consider this.
I find it odd that in Java and C# classes are non-sealed / non-final by default. I think making classes sealed greatly improves readability of the code.
Notice that this is in-house code that we can always change should the rare case occur that we need to subclass.
What are your experiences? I meet quite some resistance to this idea. Are people that lazy they could not be bothered to type sealed?
Okay, as so many other people have weighed in…
Yes, I think it’s entirely reasonable to recommend that classes are sealed by default.
This goes along with the recommendation from Josh Bloch in his excellent book Effective Java, 2nd edition:
Designing for inheritance is hard, and can make your implementation less flexible, especially if you have virtual methods, one of which calls the other. Maybe they’re overloads, maybe they’re not. The fact that one calls the other must be documented otherwise you can’t override either method safely – you don’t know when it’ll be called, or whether you’re safe to call the other method without risking a stack overflow.
Now if you later want to change which method calls which in a later version, you can’t – you’ll potentially break subclasses. So in the name of “flexibility” you’ve actually made the implementation less flexible, and had to document your implementation details more closely. That doesn’t sound like a great idea to me.
Next up is immutability – I like immutable types. I find them easier to reason about than mutable types. It’s one reason why the Joda Time API is nicer than using
DateandCalendarin Java. But an unsealed class can never be known to be immutable. If I accept a parameter of typeFoo, I may be able to rely on the properties declared inFoonot to be changed over time, but I can’t rely on the object itself not being modified – there could be a mutable property in the subclass. Heaven help me if that property is also used by an override of some virtual method. Wave goodbye to many of the benefits of immutability. (Ironically, Joda Time has very large inheritance hierarchies – often with things saying “subclasses should be immutable. The large inheritance hierarchy ofChronologymade it hard to understand when porting to C#.)Finally, there’s the aspect of overuse of inheritance. Personally I favour composition over inheritance where feasible. I love polymorphism for interfaces, and occasionally I use inheritance of implementation – but it’s rarely a great fit in my experience. Making classes sealed avoids them being inappropriately derived from where composition would be a better fit.
EDIT: I’d also like to point readers at Eric Lippert’s blog post from 2004 on why so many of the framework classes are sealed. There are plenty of places where I wish .NET provided an interface we could work to for testability, but that’s a slightly different request…