Why aren't classes sealed by default?
Asked Answered
D

9

39

I was just wondering, since the sealed keyword's existence indicates that it's the class author's decision as to whether other classes are allowed to inherit from it, why aren't classes sealed by default, with some keyword to mark them explicitly as extensible?

I know it's somewhat different, but access modifiers work this way. With the default being restrictive and fuller access only being granted with the insertion of a keyword.

There's a large chance that I haven't thought this through properly, though, so please be humane!

Dissatisfy answered 31/10, 2008 at 0:38 Comment(6)
I would argue that, if you made classes sealed by default, then that means you should NOT be using an object-oriented language.Lecythus
Too many times have I come across sealed classes within the .NET Framework that I wanted to inherit and override functionality in. Same thing goes with internal.Doradorado
a language with objects and messages but not inheritance is not object-oriented, but merely object-basedBadalona
@Chris: Of you're still unhappy about the sealed .NET Framework classes, you may find blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx to be an interesting read.Bossuet
From MSDN: To determine whether to seal a class, method, or property, you should generally consider the following two points: 1) The potential benefits that deriving classes might gain through the ability to customize your class. 2) The potential that deriving classes could modify your classes in such a way that they would no longer work correctly or as expected. . . My preference is that if it's no extra work for me as the author of a class to allow others to derive from it, I don't mark it sealed. But if it my class is not designed for derivation in some subtle way, seal it.Salvation
Interesting insight on this from a former member of the C# team - he wishes they HAD made sealed the default: #2164670Worm
A
32

In my opinion there should be no default syntax, that way you always write explicitly what you want. This forces the coder to understand/think more.

If you want a class to be inheritable then you write

public extensible class MyClass

otherwise

public sealed class MyClass

BTW I think the same should go with access modifiers, disallow default access modifiers.

Amphichroic answered 31/10, 2008 at 6:37 Comment(4)
Good point, you would always have to be clear about what you were doing rather than knowingly or unknowingly falling back on invisible defaults.Dissatisfy
you could consider the use of abstract modifier to be used for the purpose of inheritanceKamasutra
And what would happen if no keyword were provided? Just public class MyClassTheotheobald
I get your point - although things can get very verbose this way. Making sensible default, conventional decisions for the developer seems, sensibly, to be the way things are going...Worm
C
56

I'd say it was just a mistake. I know many people (including myself) who believe that classes should indeed be sealed by default. There are at least a couple of people in the C# design team in that camp. The pendulum has swung somewhat away from inheritance since C# was first designed. (It has its place, of course, but I find myself using it relatively rarely.)

For what it's worth, that's not the only mistake along the lines of being too close to Java: personally I'd rather Equals and GetHashCode weren't in object, and that you needed specific Monitor instances for locking too...

Cierracig answered 31/10, 2008 at 6:26 Comment(11)
who on the C# team were pro-sealed-class?Cornelia
Eric Lippert, and Cyrus too I believe. (I don't think either of them was on the team for v1 though.)Cierracig
If GetHashCode weren't in object then every aggregator (not even inheritor) would have to be given access to the privates of every type, and the aggregators would have to roll their own hasher for every type. Do you really really think that would lessen the amount of pain in programming?Bagger
@Windows: Neither of those would be the case. You could optionally implement equality and GetHashCode where it made sense, implementing an interface. A system IEqualityComparer could be included which did an identity comparison. Other comparisons could be based on public properties. It'd be fine.Cierracig
Three major mistakes of C#: default mutable, default unsealed, default nullable.Woodrowwoodruff
I was reading this article(blog.stephencleary.com/2010/03/…) where it redirected to your answer and the blog also says that if class is used for inheritance then it should be marked as sealed but what do we gain if we marked every class as sealed if it is not going to take part in inheritance?Karlin
@Learning-Overthinker-Confused: What exact line of the blog post are you referring to? What do you mean by "used for inheritance" and "take part in inheritance"? (Every class takes part in inheritance, in that it inherits from System.Object at least.) I think you may have misunderstood the post. Stephen writes at the end that he seals every class unless "it truly needs to be a base class".Cierracig
Ok Lets say I have a class called Product(Standalone class) and there is no class which inherits from this Product class so that reason is sufficient enough to mark product class as sealed?Karlin
@Learning-Overthinker-Confused: I would stop and ask yourself whether you can think of a reason to subclass it. If there is, that probably merits extra design work. If there isn't, seal it.Cierracig
Blog post written by Stephen Cleary says he seals every class unless "it truly needs to be a base class" so is there any performance benefit of sealing every class ? I am just trying to understand the reason why he says thatKarlin
@Learning-Overthinker-Confused: Because it makes the intent explicit. Another way of putting it is "Design for inheritance or prohibit it." That has nothing to do with performance - if there's any performance improvement, that's just a bonus.Cierracig
A
32

In my opinion there should be no default syntax, that way you always write explicitly what you want. This forces the coder to understand/think more.

If you want a class to be inheritable then you write

public extensible class MyClass

otherwise

public sealed class MyClass

BTW I think the same should go with access modifiers, disallow default access modifiers.

Amphichroic answered 31/10, 2008 at 6:37 Comment(4)
Good point, you would always have to be clear about what you were doing rather than knowingly or unknowingly falling back on invisible defaults.Dissatisfy
you could consider the use of abstract modifier to be used for the purpose of inheritanceKamasutra
And what would happen if no keyword were provided? Just public class MyClassTheotheobald
I get your point - although things can get very verbose this way. Making sensible default, conventional decisions for the developer seems, sensibly, to be the way things are going...Worm
U
12

Inheritance is a foundational principle of OO, so arguably, disallowing it by default wouldn't be intuitive.

Uplift answered 31/10, 2008 at 0:44 Comment(5)
I think that many would argue that the majority of classes are not designed to be inherited from.Gigahertz
I also argue that most developers do not construct their classes with inheritance in mind.Jamaaljamaica
Mike and Steve, if you follow good OO practices then you'll be designing classes to be inherited and reused.Doradorado
@Chris: No way. Most classes will never be derived from, and guessing which elements require specialisation not only wastes time but builds in restrictions on the course of future implementation decisions. See Effective Java for a good discussion of this.Cierracig
If I could vote up a comment, I would do so for Jon's comment here - that's the fundamental point - designing for inheritance really requires a lot of forethought and the vast majority of the time is unneeded - so why default to something which will require developers to waste brain cycles??Ar
I
4

You could probably make just as many arguments in favor of sealed-by-default as you could against it. If it were the other way around, someone would be posting the opposite question.

Irs answered 31/10, 2008 at 2:35 Comment(0)
G
3

I can't recall having heard a rationale for the decision to have classes not sealed by default. However, there are certainly quite a few people who believe that C# should have been spec'ed to have sealed be the default:

http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx

Gigahertz answered 31/10, 2008 at 0:45 Comment(0)
B
3

sealed classes prevent inheritance and therefore are an OO abombination. see this rant for details ;-)

Badalona answered 31/10, 2008 at 0:52 Comment(4)
thanks for the drive-by downvotes with no comment - cowards! :-PBadalona
Personally, I think implementation inheritance is way overstated in importance. And, I'd generally agree with the statement that the default should be sealed - it's extremely easy to screw up with inheritance. Composition should usually be used instead when feasible. So, I strongly disagree with you :) For me the principal advantages of OO development are interfaces and polymorphism.Ar
@[Phil]: so, every time you create a windows form, do you encapsulate a Form object instead of inherit from System.Windows.Form? Seems like a lot of extra work... Inheritance is fundamental; learn it, live it, love it ;-)Badalona
@StevenA.Lowe For prosperity, I should point out that Form was designed to be extended, and that's the whole point of this debate. It seems evident to you and me that one should thrive to design extensible code, however empirical evidence shows that sadly way too many people don't. Hence, having a class sealed or not has no theoretical difference; those classes can't be extended as they weren't designed for it, period. The only practical difference is that in one case it's obvious and explicit (sealed) and in the other, you get to discover it when it crashes at runtime.Schnur
C
3

Merely deriving from an unsealed class doesn't change the class's behavior. The worst that can happen is that a new version of the base class will add a member with the same name as the deriving class (in which case there will just be a compiler warning saying you should use the new or override modifier) or the base class is sealed (which is a design no-no if the class has already been released into the wild). Arbitrary sublassing still complies with the Liskov Substitution Principle.

The reason that members are not overridable by default in C# is that because overriding a method can change the base class's behaviour in a way that the base class's author didn't anticipate. By making it explicitly abstract or virtual, it's saying that the author is aware that that it can change or is otherwise beyond their control and the author should have taken this into account.

Cornelia answered 31/10, 2008 at 2:56 Comment(0)
B
3

80% of the features of Word go unused. 80% of classes don't get inherited from. In both cases, once in a while, someone comes along and wants to use or reuse a feature. Why should the original designer prohibit reuse? Let the reuser decide what they want to reuse.

Bagger answered 31/10, 2008 at 7:12 Comment(1)
That's an argument against the existence of the sealed keyword, not the default :)Dissatisfy
B
0

For the same reason why objects are not private by default

or

to be consistent with the object analogue, which is objects are not private by default

Just guessing, coz at the end of the day it's a language's design decision and what the creators say is the canon material.

Blackball answered 31/10, 2008 at 7:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.