How to set the fields of a derived class? - c#

I've 2 classes: "RootClass", and "SubClass". SubClass is derived from RootClass. How do I make a constructor in RootClass, which can set values to fields found in SubClass?
I tried:
Set the subclass's value from the root's constructor, but it doesn't see the subclass's fields.
Create a constructor in SubClass, that doesn't seem to happen. Also tried setting the constructor in root to virtual, so the sub constructor may override it, no luck either.
Instantiate SubClass in RootClass's constructor which just seem stupid.
Basically I want to have 2 classes. The SubClass is the same as RootClass with a few additional fields, which i cant seem to apply a value to.
Depending on a logic I either create a root or sub.
Clearly I'm on the wrong path here, how do I do this?

A base class wouldn't have knowledge of it children classes. What you are saying is either wrong OOP or a very unusual scenario,

How do I make a constructor in RootClass, which can set values to fields found in SubClass
You can't - as far as RootClass is concerned, SubClass doesn't exist.
Also tried setting the constructor in root to virtual, so the sub constructor may override it
You can't - constructors aren't inherited, so there's no concept of "virtual" constructors.
Here's the typical pattern for "chaining" constructors:
public class RootClass
{
public RootClass(int rootProperty)
{
this.RootProperty = rootProperty;
}
public int RootProperty {get; set;}
}
public class SubClass : RootClass
{
v--- call the base constructor
public SubClass(int rootProperty, string subProperty) : base(rootProperty)
{
this.SubProperty = subProperty;
}
public string SubProperty {get; set}
}

Perhaps you're looking for a way for SubClass to call the RootClass constructor?
public class RootClass
{
public RootClass(int foo)
{
}
}
public class SubClass: RootClass
{
public SubClass(int foo)
: base(foo) // calls RootClass constructor
{
// now set Subclass fields
}
}

You cannot access any member of the derived class from the root class.
The typical design pattern is to create a method:
virtual void Init(int a, int b) {}
in your base class, where the parameters are whatever information the derived classes would require to perform self-initialization. Call this from the constructor of the root class.
The derived class would then require a constructor
SubClass() : base() { }
which would guarantee the root class constructor is called, and then its own init method is called.
In this case, however, your best design pattern is to simply subclass.
Suppose the RootClass has member int a and the Subclass int b:
class RootClass {
int a;
RootClass(int a) {
this.a = a;
}
}
class SubClass {
int b;
SubClass(int a, int b) : base(a) {
this.b = b;
}
}

In general, base classes should not have knowledge of their subclasses' implementation details. You should be able to provide your own constructor in the subclass to instantiate its fields, like so:
class SubClass : RootClass
{
private bool subClassfield;
public SubClass() : base()
{
subClassField = true;
}
}
Does that not work as expected? Note the : base() expression, which ensures the SubClass's constructor calls the base class's constructor to guarantee the base class is initialized before proceeding.

A class can not know about the implementation of all the classes that inherit from it.

Related

Why won't this child class instantiate

I have this code:
class Parent
{
public Parent(string someArg)
{
Console.WriteLine("Parent");
}
}
class Child : Parent
{
public Child(string someArg)
{
Console.WriteLine("Child");
}
}
which I then instantiate:
var child = new Child("something");
gets me an error. I know it has to do with the parent constructor, but I'm not sure why is this the case. Am I required to use base every time I have a constructor in the parent which is not parameter-less? Why?
The base class needs initialization just as well. Therefore, when the base class only has a constructor with an appetite for parameters, you will have to feed it.
In this case, if you are overriding everything the baseclass constructor does, you could let the baseclass have a second, parameterless, constructor. And if you'd like to make use of the logic in the baseclass constructor, you really have no choice but to call : base(string)
When you declare a class it has a default parameterless constructor. If you define your own construct then default one is gone. In your case you defined a constructor with a parameter.
When you create a new instance each class in inheritance hierarchy should be constructed. Base class has the only constructor with a string parameter which is not called in your code. The implicit parameterless constructor call cannot happen as well.
So that's why you should white:
public Child(string someArg) :base(someArg) { }
Or you can bring the parameterless constructor back in you code and do not use base:
public Parent() { }
Add this at base class to solve your problem.
public Parent() {}
or make it protected to use it just for child classes
protected Parent() {}

Is there a way to leverage inheritance when including a parameter of the base class in a constructor?

From what I've read, there doesn't appear to be a good way to convert a class a base class to an inheriting class.
Following the answer in this question, I've gone ahead and just created a constructor that takes an instance of the base class as a parameter.
The constructor looks like this:
public DerivedClass(BaseClass base) {
this.Id = base.Id;
this.Foo = base.Foo;
// ..
this.NewProperty = SomeNewValue;
}
etc. This also means that if the base class gets a new property, the constructor in the derived class also needs to be modified in order to copy that property.
Is there a way to leverage the fact that the derived class inherits from the base class to make this constructor less fragile?
It seems you haven't fully grasped inheritance and you've over-thought what you need to do.
I've gone ahead and just created a constructor that takes an instance of the base class as a parameter.
You don't need to do this when extending (inheriting from) a base class, you only do this when wrapping a class.
Is there a way to leverage the fact that the derived class inherits from the base class to make this constructor less fragile?
Yes: use constructor overloading. Given this base class:
public class MyBase
{
public virtual string Name { get; set;}
}
you could do this:
public class MyExtendedClass : MyBase
{
public MyExtendedClass(string name)
{
Name = name;
}
}
but better still is to leverage constructor overloading like this, where constructor parameters are passed through to the base class constructor:
public class MyBase
{
public MyBase(string name)
{
Name = name;
}
public virtual string Name { get; set;}
}
public class MyExtendedClass : MyBase
{
public MyExtendedClass(string name) : base (name) { }
}
You would tend to pass in values on the constructor for properties that you want to be immutable. For the others, you can take advantage of inline initialization:
var myNewClass = new MyExtendedClass() { Name = "blah" };
Could you not add a protected constructor to the base class that carries out the assignments and then just pass the base class down to it as a parameter:
protected BaseClass(BaseClass source)
{
this.Id = source.Id;
this.Foo = source.Foo;
...
}
Thereby keeping the code to duplicate the base class in the base class itself?

Accessing subclass in base class... but different

I have a base class that has a subclass (could be a struct i suppose but not sure if it's appropriate) and a method.
class Base
{
protected class SubClass
{
public string word;
public int number;
}
protected void SomeMethod()
{
this.SubClass.word //this is where I'm struggling
}
}
Then i have a couple child classes that implement my baseClass, instantiate the Base.SubClass and add some values to the instantiated class.
class ChildClass1 : Base
{
public childSubClass = new SubClass();
public void DoSomethingRidiculous()
{
childSubClass.word = "WhoFarted";
}
}
class ChildClass2 : Base
{
public childSubClass = new SubClass();
public void DoSomethingRidiculous()
{
childSubClass.word = "ItStinks";
}
}
If possible, I would like to be able to get the value of SubClass.word from within the Base class. I think that my attempt at implementing my idea is probably wrong.
I'm not sure that you really need subclassing / class nesting. Just move out class SubClass declaration and declare protected field/property of SubClass type instead.
public class SubClass
{
public string word;
public int number;
}
public class Base
{
protected SubClass subClassInstance = new SubClass();
protected void SomeMethod()
{
this.subClassInstance.word //this is where I'm struggling
}
}
Then you can access subClassInstance inside both ChildClass1 and ChildClass2
The base class has no field or property of type SubClass, so you definitely cannot do what you propose directly.
One solution would be to add the field
public childSubClass = new SubClass();
to class Base itself. Is there a problem with this?
The other solution would be to use reflection to get the value of the field, assuming that the object you are reflecting on does have such a field. This is really far-fetched and while it might technically allow you to do what you propose, it has a very bad code smell.
I'm not sure why you're making a Sub Class instead of just making those two properties of the base class, but the reason you're having trouble with this line :
this.SubClass.word //this is where I'm struggling
is because you're not instantiating SubClass as a property of the base class.
A base class can not (or should not) access members of derived classes, and usually not even know about derived classes (some exceptions apply, such as in the case of the State Pattern). If the base should have access to a member, it should be declared in the base. If derived classes should also be able to use that member, then mark the member as protected.
class Base
{
protected Foo someFoo;
void Frob()
{
// can access methods/properties of someFoo instance
}
}
class Child
{
public Child()
{
someFoo = new Foo(); // child can also access someFoo
}
}

Abstract class constructor in C#

In c# we can't create an obeject of a abstact class or interface it means abstract class do not have any constructor, is it true ?
or if it have then what is it's purpose there?
As others have said, abstract classes usually have constructors (either explicitly or the default one created by the compiler) - and any derived class constructor will have to chain through the abstract class's constructor in the normal way. That's the important bit... suppose you have an abstract class which stores the name associated with an instance - because you always want a name, and you don't want to write the Name property in each concrete derived class. You might provide a constructor which takes that name and assigns it to a field... and then every subclass constructor would have to go through that constructor, so that you still knew you'd always have a name. If you want to know more about constructor chaining, read my article on it.
Here's an example of that:
public abstract class DemoBase
{
private readonly string name;
public string Name { get { return name; } }
protected DemoBase(string name)
{
this.name = name;
}
// Abstract members here, probably
}
public class FixedNameDemo : DemoBase
{
public FixedNameDemo()
: base ("Always the same name")
{
}
// Other stuff here
}
public class VariableNameDemo : DemoBase
{
public VariableNameDemo(string name)
: base(name)
{
}
// Other stuff here
}
To further answer your comment on BoltClock's answer, asbtract classes can't have private abstract methods, but they can have private constructors. Indeed, it's sometimes useful to have only private constructors in an abstract class, because it means the class can only be derived from within the program text of the same class. This allows you to create pseudo-enums:
public abstract class ArithmeticOperator
{
public static readonly ArithmeticOperator Plus = new PlusOperator();
public static readonly ArithmeticOperator Minus = new MinusOperator();
public abstract int Apply(int x, int y);
private ArithmeticOperator() {}
private class PlusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x + y;
}
}
private class MinusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x - y;
}
}
}
In this respect, an abstract private method/property could make sense - it could be accessed by the base class but provided by the derived classes within the same class's program text. However, it's prohibited by the specification. Usually, protected abstract members would solve the same problem - but not quite always.
Good question. Here's why Abstract classes need constructors even though they cannot be instantited.
In any Object oriented language like C#, object construction is an hierarchical process. Look at the code below. When you instantiate any object of type DerivedClass, it must construct the base object first before creating the object of typeof DerivedClass. Here the base class may or may not be an Abstract class. But even when you instantiate an object of a concrete type derived from an abstract class it will still need to call the constructor of the Base class before the object of DerivedClass type is created, hence you always need a constructor for Abstract class. If you have not added any constructor, C# compiler will automatically add a public parameterless constructor to the class in the generated MSIL.
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass constructor called..");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
Console.WriteLine("DerivedClass constructor called..");
}
}
DerivedClass obj = new DerivedClass();
//Output
//BaseClass constructor called..
//DerivedClass constructor called..
PS: Assuming, If Abstract base classes
are not allowed to have constructors
because they need not be instantiated,
the whole fundamentals of the object
oriented programming will go on toss.
The idea behind Abstract types are to
represent objects that have some
features and behaviours but not
complete as whole to allow independant
existence.
No. it means that operator new is not allowed to create object from this type of class.
The purpose might be that are allocated/initialized some properties of class.
abstract usually leave some methods to implement.
Regarding the interface, this structure holds only the signatures of method, delegates or events. That may be implemented in class that use interface. You cant create a object.
Read about new
EDIT:
What is the purpose of constructor in abstract class ?
When one class inherit another class, the parent class of it had to be created first while object is crated. In class do not implement some special constructor always is used default one [className()]. When you override some method then the implementation of functionality is taken form class which override the method. This is why method used in constructor should never be virtual. Same logic for abstract class, such class can have a lot of functionality, and only one method that should be implemented by child class.
Abstract classes have constructors but you can't call them directly as you can't directly instantiate abstract classes.
To answer your comment, the concept of a private abstract method or property makes no sense, because private prevents anybody else from accessing it, and abstract prevents itself from accessing it. So there would essentially be no possible way to call it.
EDIT: see Jon Skeet's answer on private constructors. Private members of other kinds cannot exist in abstract classes, though.
Abstract classes do have constructors. When you create an instance of a derived class, its parent class' constructors are called. This applies to classes derived from abstract classes as well.

Abstract class and constructor

As an abstract class cannot be instantiated, why is a constructor still allowed inside the abstract class?
public abstract class SomeClass
{
private string _label;
public SomeClass(string label)
{
_label=label;
}
}
Constructors of any derived class still have to call a constructor in the abstract class. If you don't specify any constructors at all, all derived classes will just have to use the default parameterless one supplied by the compiler.
It absolutely makes sense to have a constructor - but "public" is really equivalent to "protected" in this case.
Because you can still do the following:
public class SomeChildClass : SomeClass
{
public SomeChildClass(string label) : base(label){ }
public string GetLabel() { return _label; }
}
As you can see, the child class can call the base contructor (on the abstract class) to create an instance of itself.
Like Jon said though, public really isn't necessary. It's effectively the same as protected.

Categories