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.
Related
I'm just after a little advice on how to best organise the inheritance here. I have a class (below) that needs to use most of, and overide some of, the classes in the base ExportData class:
public class ExtendedExportData : ExportData
{
private tData _Data;
private ResStrings _diaStrings;
public ExtendedExportData(tData Data, ResStrings diaStrings)
: base(tData, diaStrings)
{
_tData = Data;
_diaStrings = diaStrings;
}
}
What isn't neccesary in this case is having to call the base constructor as none of the base class methods used in the class above require that initialisation, the constructor is only neccesary when creating an instance of the base class directly for other (verbose) purposes.
If i remove the base constructor i get an error on the sub-class constructor saying the base constructor doesn't take 0 arguments. How can i avoid this?
Here's the base class:
public class ExportData
{
private tData _Data;
private ResStrings _diaStrings;
public ExportLines(tData Data, ResStrings diaStrings)
{
_Data = Data;
_diaStrings = diaStrings;
}
}
Thanks in advance.
A constructor of the base class is always used - but when the base class has no explicitly defined constructor, C# will generate a public parameterless constructor automatically.
Similarly, if you don't explicitly mention : base(...) in your derived class, C# assumes you want to use the parameterless constructor of the base class.
As soon as you define a constructor, the parameterless constructor is not automatically generated anymore, and so you have to call : base(...).
You can easily change this by adding such a constructor to the base class:
public class ExportData
{
protected ExportData()
{
}
}
By making this constructor protected, only classes that inherit from ExportData can use this constructor, and they no longer have to include : base(...).
You can always have a parameterless constructor in the base class that does all the initialising it needs to i.e.:
public ExportData()
{
//Initialising here
}
And then in your example just call base() i.e.
public ExtendedExportData(tData Data, ResStrings diaStrings)
: base()
Couldn't you just create an empty constructor (public ExportData(){}) in ExportData class ?
Else you could do something like here.
I know that this is old question but for future similar problem solution finders I would write something else.
If I undersand this question properly there is more elegant and common solution. Just make your base class abstract. You can still call base constructor during inheritance.
More information can be found here:
Constructor of an abstract class in C#
The error is because the base class always has to be instantiated and your base class doesn't have a default constructor.
If you have functionality in your base class that's not needed in the base class review your inheritance architecture.
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.
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.
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()
{
}
}
}
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.