views:

412

answers:

10

Lets take an example in C#

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

public class Bar : Foo
{

}

Now, All the public members of Foo is accessible in Bar except the constructor. I cannot do something like

Bar bb = new Bar(1);

Why the constructors are not inheritable?

UPDATE

I do understand we can chain constructors, but I would like to know why the above construct is not valid. I am sure there should be a valid reason for it.

+4  A: 

They are (via chaining), you would have to chain the constructor in your derived object.. IE:

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

public class Bar : Foo
{
    public Bar() : base() { }
    public Bar(int j) : base(j) { }
}

The constructors in the derived objects will then chain the calls do the constructors in the base objects.

This article provides some more examples if you want further reading.

Quintin Robinson
I do understand the chaining, but why my example is not valid is what I would like to understand (I have updated the question to highlight the same)
Ramesh
I see, sorry for answering a question you didn't ask I think I read a little bit too far in.
Quintin Robinson
Thanks Quintin, your questions made me think. +1 for one of your answers for another question.
Ramesh
No problem, we are all here to think and learn, thanks too!
Quintin Robinson
A: 

I think you can do the following:

public class Bar : Foo
{
  public Bar (int i)
    : base (i)
  {
  }
}

I may be a bit off -- but it's the general idea.

Ian P
I do understand the chaining, but why my example is not valid is what I would like to understand (I have updated the question to highlight the same)
Ramesh
+7  A: 

Constructors are not inheritable because it might cause weird and unintended behavior. More specifically, if you added a new constructor to a base class, all derived classes get an instance of that constructor. That's a bad thing in some cases, because maybe your base class specifies parameters that don't make sense for your derived classes.

A commonly given example for this is that in many languages, the base class for all objects (commonly called "Object") has a constructor with no parameters. If constructors were inherited, this would mean that all objects have a parameterless constructor, and there's no way to say "I want people who make an instance of this class to provide parameters X, Y and Z, otherwise their code shouldn't compile." For many classes, it's important that certain parameters be defined for their proper function, and making constructors non-heritable is part of the way that class authors can guarantee that some parameters are always defined.

Edit to respond to comments: Ramesh points out that if constructors were inherited as he would like them to be, he could always override base class constructors using privately declared constructors in each derived class. That is certainly true, but there it a logistical problem with this strategy. It requires that writers of derived classes have to watch base classes closely and add a private constructor if they want block inheritance of the base class constructor. Not only is this a lot of work for people writing derived classes, this kind of implicit dependency across classes is exactly the sort of thing that can cause weird behavior.

Ramesh - it's not that what you describe would be impossible to add to a language. In general it's not done because that sort of behavior could confuse people and lead to a lot of extra debugging and code writing.

Quintin Robinson provides some very worthwhile responses to this question in the comments that are definitely worth reading.

James Thompson
If you add a constructor to the base class, you would be able to initialize stuff present only in that class and that is a good behavior, I am not seeing why you say its a bad thing.
Ramesh
Because you may *require* non-base members to be initialized in you derived class.
Simon Buchan
@Simon - If so, I can always override my constructors like functions
Ramesh
@Ramesh In that scenario you are asking for the least amount of control on top of that proper initialization for derived objects wouldn't be present.
Quintin Robinson
@Ramesh I see this as similar to saying Bar bar = new Foo(); And assuming since Bar inherits from and exposes a inherited constructor from Foo then Foo should have all the required knowledge to instantiate Bar. At least this is how I am seeing it as you have described, am I way off in analogy?
Quintin Robinson
@Quintin - What I am mentioning, if Bar b = new Bar(10), as it donot have any constructor it can use the base class constructor to initalize the base. But I also now understand there are places where you may wish to block inheritance of constructor as it is not valid.
Ramesh
@Ramesh So in the scenario you described, say your base has 4 public constructors and you only want your derived to have a single public constructor, then in the derived are you overriding each base constructors and marking them private to hide?
Quintin Robinson
@Ramesh On top of that consider members of the base that have been overridden in a derived class, the base ctor blindly sets values without knowledge of repercussions of the changed logic. As most other people have said it can lead unknown/weird things taking place.
Quintin Robinson
@Quintin - Yes that was my original thought, But yes it would cause an issue if new constructor is added to based class and derived class by default would inherit and derived class may not get a chance to get its own members initialized
Ramesh
@Ramesh I hope I don't sound argumentative here, I am reading this and it sounds unintentionally harsh. I am just trying to clarify different problem cases that could occur in relation to your question.
Quintin Robinson
@Quintin - I dont mind as I am learning :)
Ramesh
+1  A: 

Constructors are not inheritable for design reasons. (Note that this is the same situation in every object-oriented language of which I know.) The simple answer is that in many cases you'd really not want the same constructors as the base class to be available. See this SO thread for some more complete explanations.

Noldorin
A: 

The simple answer is that the language doesn't work that way.

The real question you are asking for though is why it doesn't work that way :-) Well it is an arbitrary choice, and it follows on from C++ and Java (and very possibly many other langauges that influenced C#).

The likely reason is that the compiler will only generate a constructor that takes no arguments and simply calls the parent is that if you want more than what the compiler makes you do it yourself. This is the best choice since odds are you do more than suply calling the parent constructor.

TofuBeer
+1  A: 

One reason why you might introduce a constructor into a class is because it makes no sense to have an instance of that class without a specific "dependency". For example, it might be a data-access class that has to have a connection to a database:

public class FooRepository
{
    public FooRepository(IDbConnection connection) { ... }
}

If all the public constructors from base classes were available, then a user of your repository class would be able to use System.Object's default constructor to create an invalid instance of your class:

var badRepository = new FooRepository();

Hiding inherited constructors by default means that you can enforce dependencies without worrying about users creating "invalid" instances.

Matt Hamilton
+1 - I understand methods do not have the need to hide, but constructor need to be for intialization reason.
Ramesh
+1  A: 

Some discussions

The basic idea is to provide as much control to the creator as possible. And you can have private bases. How'd you create the object then?

dirkgently
+2  A: 

The Foo constructor can only know how to initialize a Foo object, so it makes no sense that it should also know how to initialize any potential subclass

public class Bar : Foo
{
public Bar(int i) : base(i) { }
}

The story the constructor tells is: "Hey base class please do whatever work you need to do to be in a good state so that I can go ahead and set up myself properly".

ecoffey
+1  A: 

Suppose constructors were inheritable. How would you disable the inherited constructors in the many cases were they don't make sense for a subclass?

Rather than complicating the language with a mechanism to block inheritance, the language designers opted for simply making constructors not inheritable.

Wim Coenen
+1 - One of the precise answers
Ramesh
A: 

Really, its because the parent constructor wouldn't fully initialize the child object. A constructor is kind of a personal thing in that respect. That's why most languages don't inherit constructors.

John Ellinwood