38

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!

xyz
  • 27,223
  • 29
  • 105
  • 125
  • 4
    I would argue that, if you made classes sealed by default, then that means you should NOT be using an object-oriented language. – Jon Limjap Oct 31 '08 at 02:44
  • 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. – Chris Pietschmann Oct 31 '08 at 06:33
  • a language with objects and messages but not inheritance is not object-oriented, but merely object-based – Steven A. Lowe Mar 25 '09 at 03:05
  • 1
    @Chris: Of you're still unhappy about the sealed .NET Framework classes, you may find http://blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx to be an interesting read. – Brian May 11 '11 at 21:17
  • 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. – zumalifeguard Sep 18 '14 at 19:52
  • Interesting insight on this from a former member of the C# team - he wishes they HAD made sealed the default: http://stackoverflow.com/questions/2164170/should-i-seal-all-classes-i-know-shouldnt-ever-be-used-as-a-base-class – niico Dec 12 '16 at 13:54

9 Answers9

53

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...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • who on the C# team were pro-sealed-class? – Mark Cidade Oct 31 '08 at 06:29
  • Eric Lippert, and Cyrus too I believe. (I don't think either of them was on the team for v1 though.) – Jon Skeet Oct 31 '08 at 06:59
  • 1
    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? – Windows programmer Oct 31 '08 at 07:15
  • 10
    @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. – Jon Skeet Nov 07 '08 at 06:24
  • 12
    Three major mistakes of C#: default mutable, default unsealed, default nullable. – Den Jun 13 '16 at 15:57
  • I was reading this article(https://blog.stephencleary.com/2010/03/inheritance-in-general-and-deriving.html) 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? – I Love Stackoverflow Mar 02 '19 at 13:55
  • @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". – Jon Skeet Mar 02 '19 at 19:14
  • 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? – I Love Stackoverflow Mar 04 '19 at 06:32
  • @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. – Jon Skeet Mar 04 '19 at 07:07
  • 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 that – I Love Stackoverflow Mar 04 '19 at 07:10
  • @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. – Jon Skeet Mar 04 '19 at 07:13
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.

Pablo Retyk
  • 5,690
  • 6
  • 44
  • 59
  • Good point, you would always have to be clear about what you were doing rather than knowingly or unknowingly falling back on invisible defaults. – xyz Oct 31 '08 at 14:34
  • you could consider the use of abstract modifier to be used for the purpose of inheritance – Spoike Mar 18 '09 at 13:13
  • And what would happen if no keyword were provided? Just `public class MyClass` – cregox May 14 '13 at 22:37
  • 1
    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... – niico Dec 12 '16 at 13:54
12

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

Cory House
  • 14,235
  • 13
  • 70
  • 87
  • 39
    I think that many would argue that the majority of classes are *not* designed to be inherited from. – Michael Burr Oct 31 '08 at 01:37
  • 14
    I also argue that most developers do not construct their classes with inheritance in mind. – Steve Horn Oct 31 '08 at 02:45
  • 2
    Mike and Steve, if you follow good OO practices then you'll be designing classes to be inherited and reused. – Chris Pietschmann Oct 31 '08 at 06:29
  • 36
    @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. – Jon Skeet Oct 31 '08 at 07:07
  • 6
    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?? – Phil Dec 08 '09 at 16:25
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.

Jon B
  • 51,025
  • 31
  • 133
  • 161
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

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
3

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

Community
  • 1
  • 1
Steven A. Lowe
  • 60,273
  • 18
  • 132
  • 202
  • 1
    thanks for the drive-by downvotes with no comment - cowards! :-P – Steven A. Lowe Mar 24 '09 at 15:13
  • 3
    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. – Phil Dec 08 '09 at 16:21
  • 2
    @[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 ;-) – Steven A. Lowe Dec 08 '09 at 19:47
  • 1
    @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. – tne May 24 '15 at 03:10
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.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
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.

Windows programmer
  • 7,871
  • 1
  • 22
  • 23
  • 3
    That's an argument against the existence of the sealed keyword, not the default :) – xyz Oct 31 '08 at 14:27
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.

blizpasta
  • 2,624
  • 3
  • 25
  • 31