Constructors inheritance!!!

G

Guest

It's true that every time you add a new constructor to a parent class, you will need to modify the child class to be able to see it from there

Sample Code

public class Paren

public Parent(

// blank constructo


public int Cod

get{return this._code;
set{this._code = value;


private int _code = 0


public class Child : Paren

public Child() : base(




public class Teste

public Tester(

Child c = new Child()
c.Code = 10



Then, later I want to modify my Parent class to include a constructor that is going to receive a parameter, like this

// new constructo
public Parent(int i

this.Code = i


If I compiled all the classes, and if I try to modify my Tester class, I'm not able to see the new constructor, I'll need to add it to the child class like this

public Child(int i) : base(i



Why is that? Any other way to be able to modify my Parent classes without needing to modify all the inheritance layers?

Thank
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

The reason you don't see it is cause the Child class has no changed, and
the constructors are not inherited from Parent to Child.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation




MR. UNDERHILL said:
It's true that every time you add a new constructor to a parent class, you
will need to modify the child class to be able to see it from there?
Sample Code:

public class Parent
{
public Parent()
{
// blank constructor
}

public int Code
{
get{return this._code;}
set{this._code = value;}
}

private int _code = 0;
}

public class Child : Parent
{
public Child() : base()
{
}
}

public class Tester
{
public Tester()
{
Child c = new Child();
c.Code = 10;
}
}

Then, later I want to modify my Parent class to include a constructor that
is going to receive a parameter, like this:
// new constructor
public Parent(int i)
{
this.Code = i;
}

If I compiled all the classes, and if I try to modify my Tester class, I'm
not able to see the new constructor, I'll need to add it to the child class
like this:
public Child(int i) : base(i)
{
}


Why is that? Any other way to be able to modify my Parent classes without
needing to modify all the inheritance layers?
 
G

Guest

Do you or anybody know a reason WHY? the constructors are not inherited from Parent to Child, I noticed that already on my test but I'll like to understand WHY?. I don't see a good explanation for that, more than a constraint in the current release, hopefully enhance in the new one.


Thanks

----- Ignacio Machin ( .NET/ C# MVP ) wrote: -----

Hi,

The reason you don't see it is cause the Child class has no changed, and
the constructors are not inherited from Parent to Child.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation




MR. UNDERHILL said:
It's true that every time you add a new constructor to a parent class, you
will need to modify the child class to be able to see it from there?
{
public Parent()
{
// blank constructor
}
{
get{return this._code;}
set{this._code = value;}
}
{
public Child() : base()
{
}
}
{
public Tester()
{
Child c = new Child();
c.Code = 10;
}
}
public Parent(int i)
{
this.Code = i;
}
not able to see the new constructor, I'll need to add it to the child class
like this:
 
J

Jon Skeet [C# MVP]

MR. UNDERHILL said:
It's true that every time you add a new constructor to a parent class,
you will need to modify the child class to be able to see it from
there?

Well, you'll need to modify the child class if you want the child class
to have another constructor, yes. Constructors aren't inherited.
Why is that? Any other way to be able to modify my Parent classes
without needing to modify all the inheritance layers?

See http://www.pobox.com/~skeet/csharp/constructors.html for reasoning.
 
D

Daniel Pratt

Hi,

MR. UNDERHILL said:
Do you or anybody know a reason WHY? the constructors are not inherited
from Parent to Child, I noticed that already on my test but I'll like to
understand WHY?. I don't see a good explanation for that, more than a
constraint in the current release, hopefully enhance in the new one.

As it is now implemented, it is impossible create an instance of a class
without invoking a constructor *of that class*. This is a very useful
constraint because if you put some initalization code in all the
constructors of a class, you know the initalization code will be executed
before the instance of that class can be used. If you instead directly
invoked an inherited constructor of a class (if that were possible) that
would imply that none of the class' own constructors was *not* invoked.

To put it another way, if, by example, I create a class (let's call it
ActivityLog) that requires a valid FileStream to function correctly, I would
probably require that an instance of FileStream be passed via my class'
constructor. If someone could create an instance of ActivityLog via an
inherited constructor, ActivityLog's own constructor wouldn't be called,
ActivityLog wouldn't have a valid instance of FileStream and thus it would
be completely non-functional (to put it mildly).

Regards,
Dan
 
J

Jon Skeet [C# MVP]

MR. UNDERHILL said:
Do you or anybody know a reason WHY? the constructors are not
inherited from Parent to Child, I noticed that already on my test but
I'll like to understand WHY?. I don't see a good explanation for that,
more than a constraint in the current release, hopefully enhance in
the new one.

See http://www.pobox.com/~skeet/csharp/constructors.html

I sincerely hope constructors *don't* become inherited, and very much
doubt that they ever will.
 
A

Aaron Queenan

Why doesn't C# just automatically create constructors which match the Parent
class' UNLESS the Child defines any?

Thanks,
Aaron.
 
J

Jon Skeet [C# MVP]

Aaron Queenan said:
Why doesn't C# just automatically create constructors which match the Parent
class' UNLESS the Child defines any?

That would be a possibility, but that would still make me somewhat
uncomfortable. The thing is, constructors can't act polymorphically, so
it's really not the same kind of inheritance in the first place.
Personally I'm happy with the way it is, and it's the same way which
has served Java well for a long time.
 
G

Guest

Jon, please help on this one!!! I want to really understand or convince me about your position.

I'll be happy to decide what to do and not have the constraint. Imagine a Constructor that acts as any other Method, that if you want to create a Parent object and you want to let your Childs override the constructor then you specify the Constructor as virtual (too crazy!!!) and you can have things like

public class Client{
public override Client(){
}

or what about...

public new Client(){
}
}

Why not let the developer decide how to define the Constructors the same way you do with Methods, why needs to be different? It'll be a really powerfull Constructor and you will have all you have today, don't you think?

In my specific case, I was building a project, that have many inheritance levels and I want to add some new functionality (helpers) allowing some other options in the constructor that I didn't think about from the begining. Now I'll need to add the constructor to my parent class and go to every layer and the same thing public Constructor(int newParameter) : base(newParameter).

Thanks
 
J

Jon Skeet [C# MVP]

MR. UNDERHILL said:
Jon, please help on this one!!! I want to really understand or
convince me about your position.

I'll be happy to decide what to do and not have the constraint.
Imagine a Constructor that acts as any other Method, that if you want
to create a Parent object and you want to let your Childs override the
constructor then you specify the Constructor as virtual (too crazy!!!)
and you can have things like
public class Client{
public override Client(){
}

or what about...

public new Client(){
}
}

Could you explain exactly what you'd expect the difference between
those two to be?
Why not let the developer decide how to define the Constructors the
same way you do with Methods, why needs to be different?

Because they are fundamentally different things. Think of constructors
as being like static methods rather than instance methods. Polymorphism
(the basis of the purpose of overriding) doesn't occur without an
instance, and until the constructor has been called there *isn't* an
instance.
It'll be a
really powerfull Constructor and you will have all you have today,
don't you think?

No, I don't. For example, what would a StreamReader constructor which
took no parameters do? If constructors were inherited, you would have
to have a StreamReader constructor with no parameters, as Object has
one.
In my specific case, I was building a project, that have many
inheritance levels and I want to add some new functionality (helpers)
allowing some other options in the constructor that I didn't think
about from the begining. Now I'll need to add the constructor to my
parent class and go to every layer and the same thing public
Constructor(int newParameter) : base(newParameter).

Perhaps you actually have too many inheritance levels? I find I rarely
use inheritance directly, although when I do it's absolutely vital.
Composition is useful more often than inheritance, in my view, and that
solves the problem neatly (because you create an instance of what is
currently your parent type, and pass it to what is currently your child
type).

The only time I wish constructors *were* inherited is when defining
exceptions, and frankly I'd far rather the IDE were improved to make it
easier to give "no-op" constructors which just called the base
constructors for specified cases than altered the language.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Aaron Queenan said:
Why doesn't C# just automatically create constructors which match the Parent
class' UNLESS the Child defines any?

Because it has no sense, a constructor is intended to initialize an instance
of the class, it's the responsability of the programmer of this class to
initialize itself correctly, he is the only one that knows how to initialize
the inherited part.

Maybe you are not seeing a class as a single entity , cause as you know it
derive from other classes you are seeing it as formed with different pieces
and only under this scenario has sense the constructor generation scheme.


Cheers,
 
M

Martin Maat [EBL]

I'll be happy to decide what to do and not have the constraint.
It does open up possibilities but they are not obvious.

I have been using Delphi for about 8 years and I never gave the virtual
constructor much though. In Delphi you do get full control over whether to
call the base class's constructor or not, which of the base class's
constructor(s) to call and when in the construction sequence. I did some
pretty hefty design in Delphi and I must say I never felt the need to
anything beyond the standard C# behavior. I think I once did some
initialisation before calling the inherited constructor but I can't remember
why and it probably was to make up for some bad design decision.

One drawback of this control is that you have to call the inherited
constructor of choice from your descended class's constructor and if you
forget to do so you may break the base class's behavior (it will not be
initialized). This alone may have been a reason to kick it for C#, it
doesn't feel right that a descendant can break the base class by not doing
something.

Now, virtual constructors. What's the point? Do we ever call a constructor
after the object has been created polymorphically? No. Could that be because
there is no point to do so, ever? Yes.

Then what is it for? Suppose you have some generic code that creates objects
and at compile time it isn't known what type of objects should be created.
You could construct a big switch/case staement of a lengthy if then else if
else if.... that would have to be updated every time a new type is coded. In
that case you would want a variable, not for objects of simple values but
for classes!

This is what Delphi offers through class references. There you go, virtual
constructors suddenly make sense.


I never needed them in applications directly but the VCL (Delphi's class
tree) uses them, for instance when a form with components/controls that was
setup at design time is read from the resource file and all
components/controls need to be instantiated.

Martin.
 
A

Aaron Queenan

Of course, but fairly often you are creating a new class which adds METHODS
rather than DATA MEMBERS. Having to implement stubs for every constructor
supported by the base class (so that they can be used interchangeably) is a
nuisance.

Regards,
Aaron.
 
A

Aaron Queenan

That's what I would like about automatically creating matching constructors.
:)

Quite often my code just adds new methods to an existing class, and it is a
pain having to create (and maintain) stubs for every contstructor supported
by the base class. My class has no special construction needs, but I want a
user (programmer) to be able to use my class instead of the base class
without having to change any code except for the class name.

Regards,
Aaron.
 
A

Aaron Perrin

Sorry for the month-late follow-up…

I saw this thread on Google and wanted to show an example of where I
run into this problem occasionally. It most notably happens when I'm
implementing TemplateMethod. Although, I can't see at the C#
designers changing this anytime soon, I'd like to put it out there for
comment, at least.

See the conceptual example below:

public abstract class AbstractBase
{
public AbstractBase(System.IO.StreamWriter writer)
{
writer.WriteLine("Calling A");
A();
}

public abstract void A();
}

public class ConcreteClass : AbstractBase
{
public override void A()
{
int a = 1 + 1;
}
}

Here, I have an abstract base that's doing some stream writing behind
the scenes (the details of which I believe should be encapsulated away
from any inheriting class). I'd like the ConcreteClass to work
without having knowledge of System.IO. However, in C#, when I create
ConcreteClass, I need to redefine the constructor, along with its
parameters, forcing me to reference System.IO.

Additionally, concerning StreamWriter if inherited constructors did
exist, wouldn't the StreamWriter implementer be able to declare the
default constructor private?

I'm not saying that I have a good answer. I'm just trying to
understand why it exists as it does. Is it a dependency from the CLR?

Thanks,

Aaron
 
J

Jon Skeet [C# MVP]

Aaron Perrin said:
Sorry for the month-late follow-up=3F

I saw this thread on Google and wanted to show an example of where I
run into this problem occasionally. It most notably happens when I'm
implementing TemplateMethod. Although, I can't see at the C#
designers changing this anytime soon, I'd like to put it out there for
comment, at least.

See the conceptual example below:

public abstract class AbstractBase
{
public AbstractBase(System.IO.StreamWriter writer)
{
writer.WriteLine("Calling A");
A();
}

public abstract void A();
}

public class ConcreteClass : AbstractBase
{
public override void A()
{
int a = 1 + 1;
}
}

Here, I have an abstract base that's doing some stream writing behind
the scenes (the details of which I believe should be encapsulated away
from any inheriting class).

No - the fact that the only constructor of the abstract class takes a
StreamWriter means, "If you're going to use this class, you *must*
provide me with a StreamWriter" - and clearly that StreamWriter must be
meaningful, otherwise it wouldn't be required. How is that
"encapsulated away from any inheriting class"?
I'd like the ConcreteClass to work
without having knowledge of System.IO. However, in C#, when I create
ConcreteClass, I need to redefine the constructor, along with its
parameters, forcing me to reference System.IO.

You're not redefining the constructor - you're giving a constructor for
your class, which will have to call the constructor of the base class.
That's not redefining anything, it's *adding* something.
Additionally, concerning StreamWriter if inherited constructors did
exist, wouldn't the StreamWriter implementer be able to declare the
default constructor private?

I suppose it could be done that way - but then every time a constructor
was added to the base class, all child classes which *didn't* want that
constructor would have to be changed. Basically it makes adding a
constructor a potentially breaking change, which I don't believe is a
good situation to be in.
I'm not saying that I have a good answer. I'm just trying to
understand why it exists as it does. Is it a dependency from the CLR?

Well, the C# compiler could automatically supply constructors from the
base class, but I don't think it would be a good solution. A far better
solution (IMO) would be to have much better IDE support, so when you
*did* want to create a class with constructors matching all the base
class ones (or a subset) you could do so very easily. That can be done
without making breaking changes easy.
 
A

Aaron Perrin

Jon Skeet said:
No - the fact that the only constructor of the abstract class takes a
StreamWriter means, "If you're going to use this class, you *must*
provide me with a StreamWriter" - and clearly that StreamWriter must be
meaningful, otherwise it wouldn't be required. How is that
"encapsulated away from any inheriting class"?

In many cases you're right, but in the example I had given, the
StreamWriter is meaningful only to the class consumer, not to the
ConcreteClass.
You're not redefining the constructor - you're giving a constructor for
your class, which will have to call the constructor of the base class.
That's not redefining anything, it's *adding* something.

The annoying thing is that often it's not adding anything but space,
since the constructor just calls base() with the passed parameters.
I suppose it could be done that way - but then every time a constructor
was added to the base class, all child classes which *didn't* want that
constructor would have to be changed. Basically it makes adding a
constructor a potentially breaking change, which I don't believe is a
good situation to be in.

Very true. However, I believe that anyone changing a constructor
risks breaking the entire dependency hierarchy anyway. That's just
the fragility and accepted tradeoff of inheritance coupling.
 
J

Jon Skeet [C# MVP]

Aaron Perrin said:
In many cases you're right, but in the example I had given, the
StreamWriter is meaningful only to the class consumer, not to the
ConcreteClass.

No, it *must* be relevant to the ConcreteClass, because the way
AbstractClass was written, it *demanded* that all derived classes
passed in a StreamWriter. How can it not be relevant?
The annoying thing is that often it's not adding anything but space,
since the constructor just calls base() with the passed parameters.

So put it in a region...
Very true. However, I believe that anyone changing a constructor
risks breaking the entire dependency hierarchy anyway. That's just
the fragility and accepted tradeoff of inheritance coupling.

Changing an existing constructor is a breaking change. Adding a new
constructor which could change which constructor was called (eg adding
a new constructor taking a string when there's an existing one taking
an object) is a breaking change. Adding an unambiguously new
constructor *isn't* a breaking change - it's just adding a way of
constructing an instance which nothing currently takes advantage of.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top