In what situations should I execute a constructor of the parent class for a child class? And why use the "base" reserved word?
Exemple:
The constructor of the base class is always called. Or more exact, one constructor of the base class. If you don't specify which one (by using the base reserved word), the default constructor of the base class is called (that means the one with no arguments). If the base class has no constructor without arguments, a compiler error occurs. With the base keyword, you specify that you want to call a certain constructor. Here are some simple examples:
public class Base
{
private int _a;
public Base() // default ctor
{_a = 0;}
public Base(int a) // a ctor with an argument
{_a = a;}
}
public class Derived : Base
{
public Derived() : base(2) // call the ctor with argument "2"
{}
public Derived(bool b) // uses the ctor without argument of the base class (_a will stay 0)
{
}
}
The keyword base here is used as a generic placeholder for the name of the base class. The only other word syntactically allowed there would be this (if you want to call a constructor of the same class)
If you not use :base word for child constructor.
Default constructor of parent will be executed.
If you have some basic construnctor in base class and you have some fields in it and want to fill it using basic constructor you should use base keyword.
Related
I have a set of classes that inherit from a base...
public abstract class BaseClass
{
public BaseClass()
{
// ...
}
}
public abstract class BaseMessageClass : BaseClass
{
// ...
}
public SpecificMessageClass : BaseMessageClass
{
// ...
}
Instantiating an object like this works:
SpecificMessageClass myMessage = new SpecificMessageClass();
However, I need to change all constructors to have an optional string parameter, like this:
public abstract class BaseClass
{
public BaseClass(string optParam="whatever")
{
// ...
}
}
Now, when I try and instantiate the object with the optional argument:
SpecificMessageClass myMessage = new SpecificMessageClass("coolstring");
I get the error:
'SpecificMessageClass' does not contain a constructor that takes 1 arguments"
Is there ANY way to do this without explicitly declaring the constructors in each level of inherited class?
No.
But given that you want to inherit, I'm guessing you want the same logic to apply at all levels on some inherited field or property. If so, the closest you can get is to add a factory method like a Create<T>(string optParam="whatever") on the base class like the following:
public class BaseClass
{
public static T Create<T>(string optParam="whatever") where T : BaseClass
{
var t = new T(); //which invokes the paramterless constructor
((BaseClass)t).SomePropertyOrFieldInheritedFromTheBaseClass = optParam; //and then modifies the object however your BaseClass constructor was going to.
return t;
}
}
That would allow all implementers of the class to implement the BaseClass and get the same effect as having the optional parameter constructor.
By the way, I didn't test the above code, so you might need to tweak it slightly. But hopefully it gives the idea.
I think that's probably the closest you can get.
Constructors are special methods. If your class specifies no constructors, it will have a no-args constructor that inherits from the parent's no-args constructor. As soon as you specify a single constructor, you do not automatically get any of the parent's constructors for free. You must declare each different constructor you need.
I am having a C# abstract class which have some methods to be implemented by its children.
Though it is so, the initialization values for those children consist of two parts: one which is the same as the parent, and another one which is unique to the children.
public abstract class parentClass {
public abstract bool IsInputValid(string input); //children must implement this
public parentClass () {
//Some shared initialization
}
}
If the class is not abstract we could do something like this to implement that
public class parentClass {
public parentClass (string input) {
//Some shared initialization
}
}
public class childClass : parentClass {
public childClass (string input) : base (input) {
//Some unique initialization
}
}
But that cannot be done using abstract class and some more, the method not need not to be implemented (since it is not abstract).
So I am in a dilemma here. On one hand, I want to have some base initialization called and on the other, I also want to have some methods enforced.
So my question is, how do we normally implement such case? On one hand it is enforcing some base initialization, and on another some methods.
Note: I am new to abstract class so I would be glad to receive any inputs regarding it.
Where do I declare wrongly (if any)? If we cannot do so, is there a way to get around to produce the same result (that is, to enforce the child class to use certain signature for constructor)?
There should be no need to enforce this. You say that the base class has some common initialization and the child classes have their own specialized initialization as well.
This is enforced already, if you have this:
public abstract class Base
{
protected Base(int value) { ... }
}
Then you have a couple of guarantees:
Nobody can construct an object of the type Base since it is abstract
Nobody can construct an object that inherits from Base without indirectly calling the only existing constructor of Base, that takes an int value parameter.
The last part there is important.
A child class can deal with this type of base constructor in at least three ways:
It can provide a constructor that looks identical save the name of it, just passing the value down to the base constructor:
public class Child : Base
{
public Child(int value) : base(value) { ... }
}
It can provide a constructor that has this parameter but has additional parameters to the child class constructor as well:
public class Child : Base
{
public Child(int value, string other) : base(value) { ... }
}
It can provide a constructor that doesn't have the parameter to the base class, but manages to compute this parameter:
public class Child : Base
{
public Child(string other) : base(other.Length) { ... }
}
The last part also handles the case where the child constructor has no parameters at all:
public class Child : Base
{
public Child() : base(new Random().Next(100)) { ... }
}
Regardless of which approach you use, it is impossible to call the base class constructor without passing a value for that parameter, hence you have enforce the following:
Child classes has to be aware of the base class constructor and its parameter
But you cannot, and should not, try to enforce the presence of a particular constructor with a specific signature.
Now, having said that, what if you want to create some sort of common way to construct two distinct child classes, that has such different constructors, in such a way that code that uses them doesn't need to know the specifics of either constructor?
Enter the factory pattern (Wikipedia):
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
(quoted text copied from entry paragraph in the Wikipedia-article)
Here's a way to abstract away the presence and knowledge of such different constructors and child classes:
void Main()
{
Test(new Child1Factory());
Test(new Child2Factory());
}
public void Test(IBaseFactory baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory.Create();
}
public class Base
{
public Base(int value)
{
Console.WriteLine($"Base.ctor({value})");
}
}
public interface IBaseFactory
{
Base Create();
}
public class Child1 : Base
{
public Child1(int value) : base(value)
{
Console.WriteLine($"Child1.ctor({value})");
}
}
public class Child1Factory : IBaseFactory
{
public Base Create() => new Child1(42);
}
public class Child2 : Base
{
public Child2(string name) : base(name.Length)
{
Console.WriteLine($"Child2.ctor({name})");
}
}
public class Child2Factory : IBaseFactory
{
public Base Create() => new Child2("Meaning of life");
}
Pay special attention to the Test(...) method, as this has no knowledge of which Base child it will get, nor how to construct such an object. If you later on add new child types from Base, you will have to provide new factories as well but existing code that uses these factories should not need to be changed.
If you want a simpler factory pattern all you have to do is replace the interface and factory classes with a delegate:
void Main()
{
Test(() => new Child1(42));
Test(() => new Child2("Meaning of life"));
}
public void Test(Func<Base> baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory();
}
Final note here. Since the factory pattern means you will have to create a different type that does the actual construction of the object you can enforce the signature of that other type, either by
Adding parameters to the Create method on the factory interface
Specifying a delegate that has parameters to the factory delegate
This means you can enforce the signature of "the creation process". Still, you cannot enforce the presence or signature of a particular constructor, but the constructor is just a means to an end, create an object, and with the factory pattern you can actually formalize this pattern in your code and thus you should get what you want.
You cannot enforce the signature or even existence of constructors of your derived classes. (or any class for that matter)
I'm afraid that's the end of the story. You aren't doing anything wrong, it's just not possible.
Since you can't override constructors in c#, you cannot enforce the existence of a certain constructor in the derived class .
This means:
a constructor cannot be abstract, virtual etc
constructors aren't polymorphically
You cannot have an abstract constructor, but neither is there any need to.
All you need to do is remove the "abstract" keyword from your parentClass and you should be good to go.
1) If I define a field in a base class like
myType myField = new MyField();
Will this field be always initialized in a derived class?
2) If I initialize this field through base class default (parameterless) constructor will it be initialized in a derived class?
Assuming I do not call any :base() constructors from derived type.
My point is to instantiate field with default value only in base class and provide overridden initialization in derived classes.
Yes, fields will always be initialized. If you don't explicitly chain to any other constructors, you'll chain to base() implicitly. You'll always end up chaining right up the type hierarchy until you hit Object.
My point is to instantiate property with default value only in base class and provide overridden initialization in derived classes.
Then I suggest in the base class, you have two constructors, one of them possibly protected:
public class BaseClass
{
private MyType myField;
protected BaseClass(MyType myField)
{
this.myField = myField;
}
public BaseClass() : this(new MyType())
{
}
}
Then constructors from your derived types can chain to either constructor, as appropriate... and you don't end up creating an instance of MyType when you don't need to.
I have a class like below
public abstract class ABC
{
int _a;
public ABC(int a)
{
_a = a;
}
public abstract void computeA();
};
Is it mandatory for the derived class to supply the parameters for the base/abstract class constructor? Is there any way to initialize the derived class without supplying the parameters?
Thanks in advance.
Yes, you have to supply an argument to the base class constructor.
Of course, the derived class may have a parameterless constructor - it can call the base class constructor any way it wants. For example:
public class Foo : ABC
{
// Always pass 123 to the base class constructor
public Foo() : base(123)
{
}
}
So you don't necessarily need to pass any information to the derived class constructor, but the derived class constructor must pass information to the base class constructor, if that only exposes a parameterized constructor.
(Note that in real code Foo would also have to override computeA(), but that's irrelevant to the constructor part of the question, so I left it out of the sample.)
You can create a default constructor in a derived class that does not need parameters and the derived class will supply default values, but you cannot remove the requirement entirely. It is a manadatory condition of the base class to have some sort of value.
public MyDerivedClass : ABC
{
public MyDerivedClass()
: base(123) // hard wired default value for the base class
{
// Other things the constructor needs to do.
}
public override void computeA()
{
// Concrete definition for this method.
}
}
Add a default constructor to the base class and call the other constructor providing an initial values for its parameters:
public abstract class ABC
{
int _a;
public ABC(int a)
{
_a = a;
}
public ABC() : this(0) {}
}
It doesn't have much to do with the fact that the base class is abstract.
Because you've declared a public constructor that has 1 parameter, the compiler removes the basic empty constructor.
So, if you want to create an instance of that class, you have to pass a parameter.
When you derive from such a class, a parameter must be passed to the base class for it o construct.
What is the purpose of base() in the following code?
class mytextbox : TextBox
{
public mytextbox() : base()
{
this.Text = "stack";
}
}
Why At design time messages are displayed ؟
my code :
class Class1:TextBox
{
public Class1()
{
this.Resize += new EventHandler(Class1_Resize);
}
void Class1_Resize(object sender, EventArgs e)
{
MessageBox.Show("Resize");
}
}
base() in your code is a call to the parameterless constructor of the base-class ofmyTextBox, which happens to beTextBox. Note that this base constructor will execute before the execution of the body of the constructor in the derived class.
Every class's constructor must eventually call one of its base class's constructors, either directly or through chained constructors in the same class. Consequently, there is always an implicit / explicit base(...) or explicit this(...) call on every constructor declaration. If it is omitted, there an implicit call to base(), i.e. the parameterless constructor of the base class (this means that the call tobase()in your example is redundant). Whether such a declaration compiles or not depends on whether there exists such an accessible constructor in the base class.
EDIT:
Two trivial points:
The root of the class-hierarchy does not have a base class, so this rule does not apply to System.Object's only constructor.
The first sentence should read: "every non-System.Object class's constructor that completes successfully must eventually call one of its base class's constructors." Here is a 'turtles all the way down' example where the base class's contructor is never called: instantiating an object of such a class will obviously overflow the execution-stack.
// Contains implicit public parameterless constructor
public class Base { }
// Does not contain a constructor with either an explicit or implicit call to base()
public class Derived : Base
{
public Derived(int a)
: this() { }
public Derived()
: this(42) { }
static void Main()
{
new Derived(); //StackOverflowException
}
}
No idea, it is unnecessary. A constructor always calls the base class constructor automatically without you having to write it explicitly. But that's what it means. You'd have to write it if you don't want to call the parameterless constructor but one that takes an argument.