Why can an abstract class have constructor? [duplicate] - c#

This question already has answers here:
Constructor of an abstract class in C#
(14 answers)
Can an abstract class have a constructor?
(22 answers)
Closed 8 years ago.
Why does an abstract class have constructor? What's the point? It's obvious that we cannot create an instance of an abstract class.

One important reason is due to the fact there's an implicit call to the base constructor prior to the derived constructor execution. Keep in mind that unlike interfaces, abstract classes do contain implementation. That implementation may require field initialization or other instance members. Note the following example and the output:
abstract class Animal
{
public string DefaultMessage { get; set; }
public Animal()
{
Console.WriteLine("Animal constructor called");
DefaultMessage = "Default Speak";
}
public virtual void Speak()
{
Console.WriteLine(DefaultMessage);
}
}
class Dog : Animal
{
public Dog(): base()//base() redundant. There's an implicit call to base here.
{
Console.WriteLine("Dog constructor called");
}
public override void Speak()
{
Console.WriteLine("Custom Speak");//append new behavior
base.Speak();//Re-use base behavior too
}
}
Although we cannot directly construct an Animal with new, the constructor is implicitly called when we construct a Dog.
OUTPUT:
Animal constructor called
Dog constructor called
Custom Speak
Default Speak

You can still initialize any variables, dependencies and you can set up the signature of the constructors of the inherited classes.
You usually want abstract classes when you need to have different strategies for some particular cases, so it makes sense to be able to do everything else in the abstract class. And it's a good practice to make the constructor protected.

Related

How To Implicitly Call A Method From An Interface When An Object Is Initialized [duplicate]

This question already has answers here:
C# How to execute code after object construction (postconstruction)
(11 answers)
Closed 2 years ago.
I have an interface that I need to implement on a few winforms and I would like to be able to call a specific method when an object is initialized.
I know I can just explicitly call the method from the constructor of the class, but it would be very nice to be able to implicitly call this method on all classes that implement the interface.
Similar to Mixins in Pyhton.
I'm not sure if an interface is the way this should be done, or just simply inheriting from another class that calls the method in it's constructor, but every class will have it's own implementation of the method so the latter might not work.
Desired result:
interface AutoRun{
void CodeToRun();
}
class Foo: AutoRun {
void CodeToRun(){
Console.WriteLine("The Code Was Ran");
}
}
class Bar: AutoRun {
void CodeToRun(){
Console.WriteLine("This Other Code Was Ran");
}
}
Foo f = new Foo(); // -> "The Code Was Ran"
Bar b = new Bar(); // -> "This Other Code Was Ran"
You could use a base class. The constructor chain will always execute for every class in the inheritance chain implicitly. For method calls, it's not completely implicit, but calling base.CodeToRun() will get you whatever base implementation is in there. You can even avoid the base.CodeToRun() call if you decide you don't want it to run.
public interface IAutoRun
{
public void CodeToRun();
}
public abstract class AutoRun : IAutoRun
{
public AutoRun()
{
Console.WriteLine("Base constructor run");
}
public virtual void CodeToRun()
{
Console.WriteLine("The code was run");
}
}
public class Foo : AutoRun
{
public Foo()
{
Console.WriteLine("Derived constructor run");
}
public override void CodeToRun()
{
Console.WriteLine("Running my derived method code");
base.CodeToRun();
}
}
An interface is just a contract. So, you cannot make it run anything. But you can always put code that must be run at object creation into a constructor.
A constructor cannot be specified in an interface. But you can call a method implementing the interface in a constructor.
If you want it to happen automatically, use an abstract base class which implements this interface and calls the code to be run in its constructor. An abstract class cannot be instantiated, and abstract members must be overridden in the deriving (non abstract) classes. In a deriving class the autorun method will then run "magically" without an explicit method call.
The naming conventions in .NET tell us to start Interface names with an upper case "I".
interface IAutoRun
{
void CodeToRun();
}
abstract class AutoRunBase : IAutoRun
{
public AutoRunBase()
{
CodeToRun();
}
public abstract void CodeToRun();
}
Now let us implement a concrete class with an auto run functionality:
class Foo : AutoRunBase
{
public override void CodeToRun()
{
Console.WriteLine("Hello World");
}
}
Note that the AutoRunBase class (I use to append "Base" to abstract classes to mark them as such) calls the not yet implemented CodeToRun method in its constructor. Since you cannot call new on an abstract class, this is not a problem, because it will be overridden in the deriving classes.
The constructor of a base class is automatically called before the constructor of the derived class (in this case Foo has an implicitly declared default constructor).
var run = new Foo(); // Prints "Hello World" to the console.
The interface is not required to make this work, but it allows to separate the contract form the implementation.
If you do not use the interface, you can also declare CodeToRun as protected instead of public and thus disallow it to be called from outside.

Why inheritance from a class with private constructor is disallowed [duplicate]

This question already has answers here:
If derived class inherits the private members of a base class, then why not constructors?
(4 answers)
Closed 5 years ago.
I can't find the reason that why inheriting from a base class the a private parameterless constructor is not allowed in C#. Here's the simplest example:
public class Base
{
private Base()
{
}
public string Name { get; set; }
}
public class Derived : Base
{
public Derived(string name)
{
base.Name = name;
}
}
Compiler doesn't compile this code. Why is it so? The class is not sealed of course, and while the base class is meant not to be instantiated many times (as in Singleton), I think the derived class has every right to be instantiated with a parametered constructor many times.
Why inheritance is disallowed in this case?
Because you need a constructor to instantiate a class, and the constructor is held private by the class you want to derive. No one but the class itself is allowed access to it. For all it knows it doesn't exist! (You might want to use a private constructor for the Singleton pattern for example)
If you want to allow inheritance, but keep the constructor from called outside, you need the protected keyword.
You can't access something from another class if the private modifier is used; even from a derived class.
Have a look at this: Access Modifiers
private
The type or member can be accessed only by code in the same class or
struct.
And because the Base constructor has to be called when an instance of Derived will be created you can't use private in your case. You should use protected instead.

How to mandate the derived class to instantiate the constructor of the base class [duplicate]

This question already has answers here:
How to disable parameterless constructor in C#
(3 answers)
Closed 6 years ago.
Let's say I want to require a consumer of a class to pass a certain object to a class during initialization, to accomplish this I'd put it in the constructor.
For example:
public class Animal
{
private string _name;
public Animal(string name)
{
_name = name;
}
}
I can't create Animal without passing a Name.
Ok now in my case I have a base class Animal and I defined a bunch of different derived classes from that class like Human, Dog, Cat, etc.
My question is, I want to make it impossible to instantiate any class deriving from Human without passing a Name. There are no abstract constructors in C# and I realize that I can create a constructor for each class to receive Name and just call the base constructor but the problem is I can also create a derived class type (Human, Dog, Cat, etc.) with a parameter-less constructor and instantiate it without passing a Name and I want to make sure anyone who creates a derived class must have a constructor receiving Name. I can also do some kind of run time checking and throw an error but I'd rather have a compile time error.
In short, how do I mandate the derived class to instantiate the constructor of the base class?
The problem you have is that derived class does not "see" empty ctor in base class. To make it available to children but not to direct consumers of the base class declare empty ctor as protected.
public class Animal
{
private string _name;
public Animal(string name)
{
_name = name;
}
/*visible to children only empty ctor*/
protected Animal() {}
}
public class Dog : Animal
{}
void Main()
{
var d = new Dog();
}
User can not create Animal class without string argument, but can create derived class instance in that way.

Is it good to have a constructor in abstract class?

Is it good to have a constructor in abstract class?
is it a good programming practice to create constructor of abstract class? since abstract classes can not be initialized, their child classes are initialized.
Following is my class structure.
public abstract class Scheduler
{
private Storyboard timer;
protected Scheduler()
{
// initialize the timer here.
timer = new Storyboard();
this.PollInterval = 60;
}
}
public class TaskScheduler : Scheduler
{
public TaskScheduler()
: base()
{
}
}
Yes, it's absolutely fine. Just because the constructor can only be called by derived classes doesn't mean it won't be useful. For example, you might have an abstract class which represents a named entity of some kind - it would make sense to take the name as a constructor parameter.
It would probably be worth making the constructor protected, to make it even more obvious that you can't just call it from elsewhere.
Note that there being a constructor (or multiple constructors) in an abstract class does force derived class constructors to go through it, but it doesn't force the derived classes to have the same constructor signatures. For example:
public abstract class NamedFoo
{
private readonly string name;
public string Name { get { return name; } }
protected NamedFoo(string name)
{
this.name = name;
}
}
public class DerivedFooWithConstantName
{
public DerivedFooWithConstantName() : base("constant name")
{
}
}
In this case the derived class constructor is "removing" a parameter (by providing a constant value as the argument to the abstract class constructor) but in other cases it could "add" parameters that it required, or have a mixture.
There is absolutely no reason not to have a constructor in an abstract base class.
The abstract class is initialized and works just like any other class. The abstract keywords only do the following:
It prevents the class itself to be instantiated directly. It can only be instantiated by instantiating an inherited class. This does not change the behavior of initialization compared to a not abstract base class;
It allows you to have abstract methods, properties and events in the class.
If you e.g. do not have abstract methods, properties or events, exactly the same result can be accomplished by making the constructor of a class protected (like you did). This also prevents the class to be instantiated directly. The behavior does not change however compared to an abstract class.
The primary difference then becomes the ability to declare methods, properties and events as abstract which you can only do when the class is marked abstract.
Having constructor in abstract class can be useful at times. This question is a duplicate, and dealt great deal in an related post. Even though it specifically reference JAVA, conceptually it applies to C# also.
Can an abstract class have a constructor?
Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. CA1012: Abstract types should not have constructors
Fix the violation by changing the accessibility of the constructor from public to protected.
Example:
namespace Sample
{
public abstract class Book
{
protected Book()
{
}
}
}

Abstract constructor in C# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t I create an abstract constructor on an abstract C# class?
Why I can't declare abstract an constructor of my class like this:
public abstract class MyClass {
public abstract MyClass(int param);
}
Constructors are only applicable to the class in which they are defined, that is, they are not inherited. Base class constructors are used (you have to call one of them, even if only calling the default one automatically) but not overridden by deriving classes. You can define a constructor on an abstract base class -- it can't be used directly, but can be invoked by deriving classes. What you can't do is force a derived class to implement a specific constructor signature.
It is perfectly reasonable to have a constructor defined, typically as protected, in order to define some common set up code for all derived classes. This is especially true, perhaps, when the abstract class provides some other default behavior which relies on this set up. For example:
public abstract class Foo
{
public string Name { get; private set; }
protected Foo( string name )
{
this.Name = name;
}
}
public class Bar : Foo
{
public Bar() : base("bar")
{
...
}
}
You can't declare it abstract, but you can have a constructor on your abstract class; just remove the word abstract and provide a body for it.
Constructors are closer to static methods rather than "regular" methods. Like static methods, they can be overloaded, but not overriden. That is, they are not inherited but can be redefined.
public BaseClass
{
public BaseClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass extends BaseClass
{
public SubClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass2 extends BaseClass
{
}
new SubClass( "hello" );
SubClass.doIt( "hello" );
new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK
Constructors and static methods are never dispatched dynamically (virtually) -- You always know the concrete type you instantiate or the concrete class of the static method. That's why it makes no sense to have abstract constructor and abstract static method. That's why you can also not specify constructor and static method in interfaces.
You can even think of constructor as static factory method (and see the corresponding pattern):
MyClass obj = new MyClass(); // the way it is
MyClass obj = MyClass.new(); // think of it like this
The only case I see where it would make sense to define abstract constructor or abstract static method would be if reflection is used. In this case, you could ensure that all subclass would redefine the corresponding static method or constructor. But reflection is another topic...
Note: in languages such as Smalltalk where classes are regular objects, you can override static method and have abstract constructor. But it doesn't apply to Java because classes are not "regular" objects even if you can get them with reflection.
Abstract implies virtual. A non-default constructor can never be called polymorphically, so virtual and abstract are not allowed on constructors.
IF in a future version of C#, generics are enhanced to allow calling non-default constructors through a generic type parameter, then polymorphic calls to constructors would be possible and virtual and abstract constructors might be added as well.
What wrong with this:
public abstract class MyClass {
protected MyClass(int param)
{
}
}
In this case you oblige all derived classes to call base class constructor.
Because abstract constructors are not supported.
But a abstract class can have a constructor.
A constructor is not an ordinary method. It has a special purpose, and so is restricted to language features that make sense for that purpose. See also: Why do constructors not return values?
By definition, the class can't be instantiated directly, so in a sense, it already is abstract.

Categories