Base Class constructor problem

T

tshad

I am trying to move as much data from my child classes to my base classes
and am having a problem.

Original Class
***********************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public testClass(object initial)
{
_objInitial = initial;
}

public object First
{
get { return _objInitial; }
}
}
class BoolType2 : testClass
{
public BoolType2()
{
}
public BoolType2(bool initial)
{
_objInitial = initial;
}

}
}
***********************

This works fine. but I wanted to move the Constructors from the Child to
the Base since each type I build (boolean, string, integer, etc) will have
as little code to write.

If I moved the constructor (with a value passed) to the base, it caused an
error with the void constructor:
********************************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public testClass(object initial)
{
_objInitial = initial;
}

public object First
{
get { return _objInitial; }
}
}

class BoolType2 : testClass
{
public BoolType2()
{
}

public BoolType2(bool initial):base(initial)
{
//_objInitial = initial;
}

}
}
********************************

Now I get an error saying:

No overload for method 'testClass' takes '0' arguments

This is because I have a void constructor in my child class but not in my
base class.

But I didn't need this constructor in my initial example above. Only after
I added a constructor. It seems at that point any constructors that are in
my child class are necessary in my base class.

I found that I don't have to set it so that the child void class references
the child class (as I did with my child class with one parameter). But the
void class did have to be there.

Also, can I have my constructors in my base class but not in my child
classes?

*******************************************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public testClass()
{
}

public testClass(object initial)
{
_objInitial = initial;
}

public object First
{
get { return _objInitial; }
}
}

class BoolType2 : testClass
{
}
}
*******************************************

Thanks,

Tom
 
G

Göran Andersson

tshad said:
No overload for method 'testClass' takes '0' arguments

This is because I have a void constructor in my child class but not in my
base class.

Actually it's because you are not specifying which constructor in the
base class to call, and there is no parameterless constructor that can
be called by default.

Every constructor has to call a constructor in the base class. If you
don't specify one, the parameterless constructor is called by default.
As there is no parameterless constructor in the base class, you get the
error message above.
But I didn't need this constructor in my initial example above. Only after
I added a constructor. It seems at that point any constructors that are in
my child class are necessary in my base class.

No, there is no such relation between the constructors.
Also, can I have my constructors in my base class but not in my child
classes?

If you don't specify any constructor, a parameterless constructor is
created by default. That means that you can create instances of the
child class, but you can't specify the initial value.

A constructor in a class can only create instances of that class, not of
any other class. Constructors are not inherited.
 
T

tshad

Göran Andersson said:
Actually it's because you are not specifying which constructor in the base
class to call, and there is no parameterless constructor that can be
called by default.

Every constructor has to call a constructor in the base class. If you
don't specify one, the parameterless constructor is called by default. As
there is no parameterless constructor in the base class, you get the error
message above.


No, there is no such relation between the constructors.

But then the question still stands. Why did I get an error in this
situation?

********************************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public testClass(object initial)
{
_objInitial = initial;
}
public object First
{
get { return _objInitial; }
}
}
class BoolType2 : testClass
{
public BoolType2()
{
}

public BoolType2(bool initial):base(initial)
{
//_objInitial = initial;
}
}
}
********************************

This gave me an error:

No overload for method 'testClass' takes '0' arguments

There is default constructor in my child class, so why did it give an error?

As I mentioned before there was no error, if I didn't have the constructor
with the parameter.

Thanks,

Tom
 
G

Göran Andersson

tshad said:
But then the question still stands. Why did I get an error in this
situation?

8< snip
This gave me an error:

No overload for method 'testClass' takes '0' arguments

There is default constructor in my child class,

You mean a parameterless constructor.
so why did it give an error?

Because the parameterless constructor in the child class doesn't specify
which constructor to call in the base class. Therefore it by default
calls the parameterless constructor in the base class, but there is no
parameterless constructor on the base class.
As I mentioned before there was no error, if I didn't have the constructor
with the parameter.

Then the constructor in the base class didn't have a parameter, so that
it could be called by default.
 
J

Jeff Louie

Tom... If you declare any constructor in the base class then the
compiler will
not auto generate a parameterless base class constructor. The following
will
not compile since there is no auto generated base class constructor for
public
testClass().

using System;
using System.Collections.Generic;
using System.Text;

namespace TestConstructor1
{
class Program
{
static void Main(string[] args)
{
}
}

abstract class testClass
{
protected object _objInitial;

public testClass(object initial)
{
_objInitial = initial;
}
}

class BoolType2 : testClass
{
public BoolType2()
{
}

}

}

Regards,
Jeff
 
T

tshad

I think I see now, sort of. The child class makes the difference. If there
is no child class, it doesn't matter what you do with the class. It can
have a parameterless constructor or not, even if it has another constructor.
That doesn't matter.

If I don't have a child class inheriting the base class, I don't need a
default class. This compiles fine. Not sure why this is - if it isn't with
a child defined (even if the child doesn't have a parameterless
constructor).

This works fine (whether or not the class is abstract).
*********************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public testClass(object initial)
{
_objInitial = initial;
}

public object First
{
get { return _objInitial; }
}
}

}
********************

If I have a child class, I HAVE to have a parameterless constructor in the
base class. It can be defined or no constructor at all and it will create a
default one for me.

This works:
***********************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public object First
{
get { return _objInitial; }
}
}

class BoolType2 : testClass
{
}
}
***********************

And this works:

***************************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;

public testClass()
{
}

public testClass(object initial)
{
_objInitial = initial;
}

public object First
{
get { return _objInitial; }
}
}

class BoolType2 : testClass
{
}
}
***************************

But this doesn't:

*****************************
using System;
using System.IO;

namespace FtsData
{
abstract class testClass
{
protected object _objInitial;


public testClass(object initial)
{
_objInitial = initial;
}

public object First
{
get { return _objInitial; }
}
}

class BoolType2 : testClass
{
}
}
*****************************

I assume that that is because
 
G

Göran Andersson

tshad said:
If I have a child class, I HAVE to have a parameterless constructor in the
base class.

Not at all.

You just have to specify which constructor to call from the child
constructor if there is no parameterless constructor in the base class:

abstract class testClass {

protected object _objInitial;

public testClass(object initial) {
_objInitial = initial;
}

public object First {
get { return _objInitial; }
}

}

class BoolType2 : testClass {

public BoolType2() : base (false) {}

}
 
T

tshad

Göran Andersson said:
Not at all.

You just have to specify which constructor to call from the child
constructor if there is no parameterless constructor in the base class:

So in the case where I have no constructor in the child class, it will try
to call the default constructor of the child class as well as the default
constructor of the base class (since I didn't tell it which constructor to
use)?

A constructor for a base class will always be called for a child class? And
will call the following constructors in the base:
1) the constructor specified by the child class first if there.
2) the parameterless constructor of the base if there and nothing specified
by the child constructor
3) will call the default if 1 and 2 are not handled.

Thanks,

Tom
 
G

Göran Andersson

tshad said:
So in the case where I have no constructor in the child class, it will try
to call the default constructor of the child class as well as the default
constructor of the base class (since I didn't tell it which constructor to
use)?

Yes, a parameterless constructor is created for the child class, just as
if you had put this code in it:

public BoolType2() : base() {}
A constructor for a base class will always be called for a child class?
Yes.

And will call the following constructors in the base:
1) the constructor specified by the child class first if there.
2) the parameterless constructor of the base if there and nothing specified
by the child constructor
3) will call the default if 1 and 2 are not handled.

It's simpler than that:

1) If the constructor in the child class specifies a constructor to
call, that will be called.
2) Otherwise the parameterless constructor in the base class will be called.

A constructor may call a constructor in the same class instead, but
somewhere along the line it ends in calling a constructor in the base
class. Example:

public class BoolType2 {

public BoolType2(bool value) : base(value) {}

public BoolType2() : this(false) {}

}
 
T

tshad

Göran Andersson said:
Yes, a parameterless constructor is created for the child class, just as
if you had put this code in it:

public BoolType2() : base() {}


It's simpler than that:

1) If the constructor in the child class specifies a constructor to call,
that will be called.
2) Otherwise the parameterless constructor in the base class will be
called.

Got it.

And if there is no constructor in either, then the default constructor will
be called for both the child and the base (base gets executed first then the
child).

Thanks,

Tom
 

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