38

I'm guessing there's something really basic about C# inheritance that I don't understand. Would someone please enlighten me?

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
Esteban Araya
  • 29,284
  • 24
  • 107
  • 141

5 Answers5

35

Sometimes, when subclassing, you want to restrict the conditions required to create an instance of the class.

Let me give you an example. If classes did inherit their superclass constructors, all classes would have the parameterless constructor from Object. Obviously that's not correct.

recursive
  • 83,943
  • 34
  • 151
  • 241
  • 6
    This explains why it's not done by default, not why it isn't allowed in general. I.e. why not be able to specify a constructor as `virtual` ... – Noon Silk May 03 '10 at 07:31
  • The designers of C# (and Java), could easily have defined a rule that says that the constructor in `Object` is not inherited, but still invoked implicitly. – Derek Mahar Mar 27 '11 at 11:42
  • 1
    I dont know about C# but you can define a identical constructor in the child and then just call super(p1,p2...pn) – sherif Nov 16 '12 at 14:17
  • 1
    I think in that case we could override base class's constructor. It's all about being more specific, and if not, reusing the general. – Saeed Neamati May 07 '14 at 06:48
29

If you think about what would happen if constructors were inherited, you should start to see the problem.

As nearly every type in .NET inherits from Object (which has a parameterless constructor), that means almost every type that you create would be forced to have a parameterless constructor. But there are many types where a parameterless constructor doesn't make sense.

There would also be a problem with versioning. If a new version of your base type appears with a new constructor, you would automatically get a new constructor in your derived type. This would be a bad thing, and a specific instance of the fragile base class problem.

There's also a more philosophical argument. Inheritance is about type responsibilities (this is what I do). Constructors are about type collaboration (this is what I need). So inheriting constructors would be mixing type responsibility with type collaboration, whereas those two concepts should really remain separate.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
HTTP 410
  • 17,300
  • 12
  • 76
  • 127
  • +1 for the remark about forcing all classes to have a parameterless constructor. I don't understand the remark about the versioning problem though. This is no different from regular method inheritance, where it is not a problem. – Wim Coenen Mar 06 '09 at 01:47
  • Yup, this can also be a problem with regular method inheritance - sometimes known as the "fragile base class" problem - see http://en.wikipedia.org/wiki/Fragile_base_class – HTTP 410 Mar 06 '09 at 02:12
  • did not understand the philosophical argument – Cui Pengfei 崔鹏飞 May 08 '12 at 00:50
  • 1
    @CuiPengFui, inheritance is about type responsibilities (this is what I do). Constructors are about type collaboration (this is what I need). So it sort of makes philosophical sense (if you look at it sideways) that constructors aren't inherited - the 2 concepts are mainly orthogonal. – HTTP 410 May 08 '12 at 17:32
  • 2
    @CuiPengFui in other words, when you inherit methods, you inherit behavior - but if you inherit constructors, you are inheriting the *needs* of the base-class. So constructor inheritance arguably implies that the author of a base-class can predict the needs of any class that might extend it in the future. I wrote a longer explanation on this subject [here](http://stackoverflow.com/a/17472936/283851) – mindplay.dk Jul 04 '13 at 14:39
12

Constructors in superclasses are called, whether you explicitly call them or not. They chain from the parent class down. If your constructor doesn't explicitly call a constructor in it's superclass then the default constructor in that class is called implicitly before the code of your constructor.

cletus
  • 616,129
  • 168
  • 910
  • 942
2

I assume you mean:

class Foo
{
   public Foo(int someVar) {}
}

class Bar : Foo
{
    // Why does Bar not automatically have compiler generated version of 
    Bar(int someVar): Foo(someVar) {}
}

I believe this is inherited from C++ (and Java).
But assuming you did have this and Bar had some other member variables. Would this not introduce the posability of the compiler generated constructor accdently being used and not initialising the members of BAr.

Martin York
  • 257,169
  • 86
  • 333
  • 562
0

The default constructor will always be called .

class Bar : Foo { }

When Bar is instantiated it will call the Foo() constructor by default.

class Foo {
    public Foo(int someVar) {}
}

class Bar : Foo {
    public Bar() : base(42) {}
}

If there is not parameterless constructor you will be required to define which one to use and pass the parameters.

toad
  • 1,351
  • 8
  • 14