Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I recommend sealing classes by default?

Tags:

java

c#

.net

oop

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?

like image 382
Carlo V. Dango Avatar asked Jun 17 '11 17:06

Carlo V. Dango


People also ask

What is the point of sealed classes?

A sealed class, in C#, is a class that cannot be inherited by any class but can be instantiated. The design intent of a sealed class is to indicate that the class is specialized and there is no need to extend it to provide any additional functionality through inheritance to override its behavior.

When should a class be sealed?

The main purpose of a sealed class is to take away the inheritance feature from the class users so they cannot derive a class from it. One of the best usage of sealed classes is when you have a class with static members. For example, the Pens and Brushes classes of the System.

Are Sealed classes faster?

sealed classes will be at least a tiny bit faster, but sometimes can be waayyy faster... if the JIT Optimizer can inline calls that would have otherwise been virtual calls. So, where there's oft-called methods that are small enough to be inlined, definitely consider sealing the class.

Why would you seal a class C#?

We use sealed classes to prevent inheritance. As we cannot inherit from a sealed class, the methods in the sealed class cannot be manipulated from other classes. It helps to prevent security issues.


1 Answers

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:

Design for inheritance, or prohibit it.

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 Date and Calendar in Java. But an unsealed class can never be known to be immutable. If I accept a parameter of type Foo, I may be able to rely on the properties declared in Foo not 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 of Chronology made 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...

like image 160
Jon Skeet Avatar answered Oct 13 '22 20:10

Jon Skeet