I'm sure this question is somewhere else but can't find it.
I have an abstract class that will be the base for other classes.
want for the base class to have its base constructor inaccessible, and for the child classes not being able to edit the behavior, forcing them to use another constructor.
public abstract class BaseClass
{
protected int X;
private BaseClass() { } // Problematic accessor
public BaseClass(int x)
{
X = x;
}
}
public class Child : BaseClass
{
public Child(int x)
{
X = x + 5;
}
}
If I set the BaseClass() base constructor private it doesn't compile, but if I set it to protected, Child can override it.
There is a way to block Child modifying the base constructor?
EDIT: I want the base constructor to be inaccessible outside the class too.
If you don't want do anything in the
BaseClass()
constructor, just remove it (BaseClass has an explicit constructor and that's why doesn't have a default one):
public abstract class BaseClass
{
//TODO: probably you want a property to read X
private int X; // <- private looks better for fields
public BaseClass(int x)
{
X = x;
}
}
As for Child class you have to invoke its base constructor, i.e. base(int x):
public class Child : BaseClass
{
public Child(int x)
: base(x + 5) // since X is private, let's move logic into the call
{
}
}
You need to use the correct base class constructor to do what you want:
public class Child : BaseClass
{
public Child(int x) : base(x)
{
X = X + 5;
}
}
Note that the Child constructor body now uses the protected field X, not the parameter x.
Just omit the parameter-less constructor altogether. Now, every derived class is forced to call public BaseClass(int x).
Related
I have a question regards chaining constructors I read some question on StackOverflow and some c# articles but I cannot understand the topic fully. So I have a BaseClass that is inherited by DerivedClass. In the DerivedClass, I have no argument constructor but it's calling the base constructor using: base() and it also passing a value. Is this the primary purpose of the base keyword used in the constructor to pass a value to the inherited class from the derived one or is something more out there. And also in the derived class, we have a second constructor that takes 1 parameter and its using: this(). I can't understand why when I remove: this() from this constructor "VS" tells me "There is no argument given that corresponds to the required formal parameter "i" of BaseClass.BaseClass(int) ? Why I can't just have one argument constructor in the DerivedClass without using this()?
public class BaseClass
{
protected int _Num;
public BaseClass(int i)
{
_Num = i;
}
public int Num { get => this._Num ; set => _Num = value; }
}
public class DerivedClassA : BaseClass
{
private string _Name;
private int _AnotherValue;
public string Name { get => this._Name ; set => this._Name = value; }
public int AnotherValue { get => this._AnotherValue; set => this._AnotherValue = value; }
public DerivedClassA() : base(123)
{
_Name = "testing";
}
public DerivedClassA(int param2) : this() <-- Why i can't compile the program without the this() keyword here ?
{
AnotherValue = param2;
}
}
public class Program
{
public static void Main(string[] args)
{
DerivedClassA objA = new DerivedClassA(5);
}
}
I can't find a duplicate that exactly matches, so I'll provide an answer.
Imagine these classes:
public class Base
{
public Base()
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
Try it online
When you initialize a derived class, you have to first initialize the base. In our example above, the Base class has a parameterless constructor, so the derived class can implicitly call it. If we add a base second constructor, this logic remains true, and the parameterless constructor will still be implicitly called:
public class Base
{
public Base()
{
}
public Base(int a)
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
Try it online
But if we take away the parameterless constructor, Derived must now call the base constructor explicitly:
public class Base
{
public Base(int a)
{
}
}
public class Derived : Base
{
public Derived() : base(1)
{
}
}
Try it online
So what happens if we add an extra derived class constructor? Well, that also has to call the base class (either directly, or indirectly):
public class Base
{
public Base(int a)
{
// this method body is executed first
}
}
public class DerivedA : Base
{
public DerivedA(string name, int val) : base(val)
{
// this method body is executed second (last if you used this constructor, e.g. new DerivedA("hello", 1) )
}
public DerivedA() : this("test", 5) // this will call the constructor above, which will first call base. So the final chain is: base, constructor above, this constructor
{
// this method body is executed third (last if you used this constructor, e.g. new DerivedA() )
}
}
public class DerivedB : Base
{
public DerivedB(string name, int val) : base(val)
{
}
public DerivedB() : base(5) // this will call the base constructor, and then this constructor. The constructor above will not be used.
{
}
}
Try it online
Note that all classes have a parameterless constructor when no other constructor is defined, so the following two examples are equivalent:
public class BaseA
{
}
public class BaseB
{
public BaseB()
{
}
}
You'll note that SharpLab shows the compiler removed the empty constructor from BaseB() since it's superfluous.
Finally, a derived class without an explicitly defined constructor, will still call the base class constructor implicitly:
public class Base
{
public Base()
{
// this method body is executed first
Console.WriteLine("Base constructor");
}
}
public class Derived : Base
{
}
Try it online
So to summarise: unless your base class has a parameterless constructor, your derived class constructors have to either call a base constructor directly, or indirectly through another derived class constructor. Obviously you only need to call a single base constructor method, as with any other class instantiation. You don't need matching derived methods for each base method, so long as you can construct the base with the values you do have.
If I have this code in C#:
public abstract class Parent
{
private int x;
public Parent(int x)
{
this.x = x;
}
public abstract void foo;
}
public class Child
{
public override void foo()
{
x = x + 10;
}
}
I get error that:
Parent does not contain constructor that takes 0 arguments.
How can I fix it, without creating non-parametric constructor?
You can create a constructor in Child, e.g.
public Child(int x) : base(x)
{
}
Constructors are not inherited - but if you don't supply any constructors at all, the C# compiler tries to create one equivalent to this:
public Child() : base()
{
}
That's what's failing here, because there isn't a parameterless base constructor to call.
Your derived class constructor doesn't have to have the same parameters as the base class constructor of course - so long as it passes appropriate arguments to a base constructor, that's fine. For example, you could write:
public Child() : base(0) // Default to x = 0
{
}
See my article on constructors for more details.
By manually invoking Parent's constructor:
public class Child: Parent {
public Child( )
: base(0) { }
public override void foo( ) {
x = x + 10;
}
}
That is because there is an Implicit call to a constructor with zero argument.
So you need to add an explicit call:
public Child(int x) : base(x)
{
}
Or instead, you can add zero argument contructor in parent itself:
public parent() { }
I have a base class and 2 inheriting classes, and I need to use the base class properties
in different way in each of the inheriting classes. what would be the elegant way of implementing it?
I have a class basic that have maintains two different averages.
and the inheriting classes have a same method getAction(), and each one of them does a different calculation and base on the calculation it returns an action.
I want to have one instance of the averages for both of the inheriting classes.
Avoid inheritance if you can. The solution below is an implementation of the strategy pattern which should suit your needs perfectly.
class Params
{
public int First {get;set;}
public int Second {get;set;}
}
interface IAverageCounter
{
double Calculate(Params parameters);
}
class SomeAverage : IAverageCounter
{
public double Calculate(Params parameters)
{
return (parameters.First + parameters.Second) / 2;
}
}
class OtherAverage : IAverageCounter
{
public double Calculate(Params parameters)
{
return (parameters.Second - parameters.First) / 2
}
}
I would override the methods you need:
MSDN
Use the override modifier to modify a method, a property, an indexer,
or an event. An override method provides a new implementation of a
member inherited from a base class. The method overridden by an
override declaration is known as the overridden base method. The
overridden base method must have the same signature as the override
method.
public class BaseClass
{
public double x;
// Constructor:
public Square(double x)
{
this.x = x;
}
public virtual double Area()
{
return x*x;
}
}
class InhertingClass1: BaseClass
{
// Constructor:
public Cube(double x): base(x)
{
}
// Calling the Area base method:
public override double Area()
{
return (6*(base.Area()));
}
}
class InhertingClass2: BaseClass
{
// Constructor:
public Cube(double x): base(x)
{
}
// Calling the Area base method:
public override double Area()
{
return (15*(base.Area()));
}
}
I am writing an abstract base class. I want all the classes that inherit from it to inherit a constructor that basically does the same things for all the classes. Is this possible?
Doing your constructor protected will do the stuff
public abstract class A
{
protected A(string v) { V = v; }
public string V { get; protected set; }
}
public class AA : A
{
public AA(string v) : base (v) {}
}
If the abstract base class has a default constructor (i.e. a constructor with no parameters), it will automatically be called by the derived classes constructors, unless they explicitly call another constructor of the base class.
abstract class B
{
protected B()
{
...
}
protected B(object foo)
{
...
}
}
class D : B
{
public D()
: base() // not actually necessary, since it's called implicitly
{
}
public D(object foo)
: base(foo)
{
}
}
In your derived classes constructor, you will need to call your base constructor like so:
base(param1,param2,...)
If you do not call the base constructor explicitly, the default constructor in the base class will be called, if one exists. If not, you will get a compile error.
i have wrote the following polymorphic code:
public abstract class A
{
readonly int x;
A(int i_MyInt)
{
x = i_MyInt;
}
}
public abstract class B : A
{
//holds few integers and some methods
}
// concrete object class
public class C : B
{
// holds some variables and mathods
C(int MyInt)
{
// here i would like to initialize A's x
}
}
how can i initialize A's x from C
i tried passing parameters to A's C'tor - but didn't work..
Please Help,
Thanks in advance
Amitos80
You need to add a constructor to B that takes an integer and passes it to A's constructor. You can then call this constructor from C.
public abstract class B : A
{
public B(int myInt) : base(myInt)
{
// other initialization here...
}
}
public class C : B
{
// holds some variables and mathods
public C(int myInt) : base(myInt)
{
// other initialization here...
}
}
A's constructor must also not be private.