Pass a derived class reference to a base class reference - c#

Pass a derived class reference to a base class reference
does this means that call a base class from the derived class, like the constructor triangle will call the base class?
class Shape {
public int width, height;
public Shape(int x) {
width = height = x;
}
}
class Triangle : Shape {
public string style;
public Triangle(int x) : base(x) {
style = "isosceles";
}
}

Yes, it will instruct the runtime to invoke that base Shape constructor before Triangle's.
The logic executes in this order:
Execute Shape(int x)
Execute Triangle(int x)
You can therefore direct calls to different constructor overloads if you have them. Also note that if your base class has a parameterless constructor, there's essentially an implicit base() added if you do not specify one. That means if your base class does not have a parameterless constructor, all subclasses must make a valid base(...parameters...) in their constructor.
Also, you can use this() instead of base to target a constructor on the current subclass class.
public class MyBaseClass
{
public MyBaseClass()
{
Console.WriteLine("MyBaseClass Parameterless");
}
public MyBaseClass(string message)
{
Console.WriteLine("MyBaseClass Message: " + message);
}
}
public class MySubClass
{
public MySubClass()
{
Console.WriteLine("MySubClass Parameterless");
}
public MySubClass(string message)
: base(message)
{
Console.WriteLine("MySubClass Message: " + message);
}
public MySubClass(bool someUselessFlag)
: this()
{
Console.WriteLine("MySubClass bool someUselessFlag constructor");
}
}
The outputs would be:
var a = new MySubClass();
//outputs:
//MyBaseClass Parameterless
//MySubClass Parameterless
var b = new MySubClass("Hello World!");
//outputs:
//MyBaseClass Message: Hello World!
//MySubClass Message: Hello World!
var c = new MySubClass(true);
//outputs:
//MyBaseClass Parameterless
//MySubClass Parameterless
//MySubClass bool someUselessFlag constructor
Constructors chain on themselves until they eventually call the Object() base constructor. That's why var c = new MySubClass(true) calls more than two constructors.

With the help of the book C# 4.0 - The Complete Reference by Herbert Schildt. I'll try to answer this question. I think the example of the question is incomplete. If this question was raised while reading one of Herbert Schildt's C# book. Then the example may be like this:
class Shape
{
public int width, height;
public Shape(int x)
{
width = height = x;
}
public Shape(Shape shape)
{
width = shape.width;
height = shape.height;
}
}
class Triangle : Shape
{
public string style;
public Triangle(int x)
: base(x)
{
style = "isosceles";
}
public Triangle(Triangle triangle)
: base(triangle)
{
style = triangle.style;
}
}
class Draw
{
static void Main()
{
Triangle triangle1 = new Triangle(5);
Triangle triangle2 = new Triangle(triangle1);
}
}
Here second constructor of the Triangle receives a Triangle object and pass this to the Shape constructor which is base type. And this is an example of passing a derived class reference to a base class reference. For more about this see page 299 of
Herbert Schildt's book.

Related

Base() and This() in constructors. (Chained constructors)

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.

C# abstract generic method call

With the abstract following class:
public abstract class A
{
public static string MyMethod()
{
return "a";
}
}
Why can't I built this derived abstract class:
public class B<T> where T : A
{
public void AnotherMethod()
{
var S1 = base.MyMethod(); // not allowed
var S2 = T.MyMethod(); // not allowed
}
}
I don't understand why since MyMethod will be available in type T.
There are two misconceptions in your question that collectively prevent both your attempts from working.
First your B class is not in any way derived from the A class, you have only said that it takes a generic parameter that must inherit from A.
Second as the user #recursive pointed out, static methods do not participate in inheritance so MyMethod would only ever be available as A.MyMethod()
You can make at least your first attempt work if you remove the static modifier and make B inherit from A instead of using generics.
// Removed the static modifier
public abstract class A
{
public string MyMethod()
{
return "a";
}
}
// Made B inherit directly from A
public class B : A
{
public void AnotherMethod()
{
var S1 = base.MyMethod(); //base technically isn't required
}
}
Aside from the fact that A.MyMethod is static, which clearly will not work since anything static does not take part in inheritance, even if you made it not static it still will not work. For example, this will not work either:
public abstract class A {
public string MyMethod() {
return "a";
}
}
public class B<T> where T : A {
public void AnotherMethod() {
var S1 = base.MyMethod(); // Line 1
var S2 = T.MyMethod(); // Line 2
}
}
Why?
You are saying where T : A which means that type T has to be a derived type from A. Your class B<T is not a derived type of A so Line 1 will not work.
But why is Line 2 not working?
T is a type and if T is inheriting A, then objects of type T will be able to do that. If you changed it like this, then it will work:
public abstract class A {
public string MyMethod() {
return "a";
}
}
public class B<T> where T : A {
public void AnotherMethod(T t) {
t.MyMethod();
}
}
public class C : A {
}
public class BClosed : B<C> {
public void Foo(C c) {
c.MyMethod();
this.AnotherMethod(c);
}
}
In the above code, C derives A which was your restriction. Then BClosed closes the generic type saying T is C so now you can call MyMethod of A and AnotherMethod of your generic.
Also, when you have a generic class you should use the generic type otherwise I do not see the use. So this is useless since it has no generic code:
public class B<T> where T : A {
public void AnotherMethod() {
}
}

Block base constructor to child class

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).

Parent does not contain constructor that takes 0 arguments

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() { }

how to make 2 inheriting classes share the same base class properties?

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()));
}
}

Categories

Resources