Why is it possible to write constructor for an abstract class in C#?
As far as I know we can't instantiate an abstract class.. so what is it for?
You can't instantiate the class, right?
Because there might be a standard way you want to instantiate data in the abstract class. That way you can have classes that inherit from that class call the base constructor.
public abstract class A{
private string data;
protected A(string myString){
data = myString;
}
}
public class B : A {
B(string myString) : base(myString){}
}
Far as I know we can't instantiate an abstract class
There's your error right there. Of course you can instantiate an abstract class.
abstract class Animal {}
class Giraffe : Animal {}
...
Animal animal = new Giraffe();
There's an instance of Animal right there. You instantiate an abstract class by making a concrete class derived from it, and instantiating that. Remember, an instance of a derived concrete class is also an instance of its abstract base class. An instance of Giraffe is also an instance of Animal even if Animal is abstract.
Given that you can instantiate an abstract class, it needs to have a constructor like any other class, to ensure that its invariants are met.
Now, a static class is a class you actually cannot instantiate, and you'll notice that it is not legal to make an instance constructor in a static class.
It's a way to enforce a set of invariants of the abstract class. That is, no matter what the subclass does, you want to make sure some things are always true of the base class... example:
abstract class Foo
{
public DateTime TimeCreated {get; private set;}
protected Foo()
{
this.TimeCreated = DateTime.Now;
}
}
abstract class Bar : Foo
{
public Bar() : base() //Bar's constructor's must call Foo's parameterless constructor.
{ }
}
Don't think of a constructor as the dual of the new operator. The constructor's only purpose is to ensure that you have an object in a valid state before you start using it. It just happens to be that we usually call it through a new operator.
Key Points About Abstract Class
An abstract class cannot be instantiated.
An abstract class can have constructor and destructor.
An abstract class cannot be a sealed class because the sealed
modifier prevents a class from being inherited.
An abstract class contains abstract as well as non-abstract members.
An abstract class members can be private, protected and internal.
Abstract members cannot have a private access modifier.
Abstract members are implicitly virtual and must be implemented by a
non-abstract derived class.
Adding to the above answers and examples.
Yes, an abstract class can have a constructor, even though an abstract class cannot be instantiated. An abstract class constructor c# code example will be explained. But, the next question can also be arises, as if we cannot instantiate (construct an object using new) an abstract class, then what for a constructor is in an abstract class or why should we use a constructor in abstract class?
Note that when we create an object of a derived class then the constructor of the abstract base class is implicitly called, even though we cannot instantiate an abstract class. For example in the program, if we create an object of a derived class then the abstract base class constructor will also be called.
This is also one of the example
Examples
abstract class A
{
protected A() {Console.WriteLine("Abstract class constructor"); }
}
//Derived class
class B : A
{
public B() {Console.WriteLine("Derived class constructor"); }
}
class Program
{
static void Main(string[] args)
{
B obj = new B();
}
}
Output will be
Abstract class constructor
Derived class constructor
It's there to enforce some initialization logic required by all implementations of your abstract class, or any methods you have implemented on your abstract class (not all the methods on your abstract class have to be abstract, some can be implemented).
Any class which inherits from your abstract base class will be obliged to call the base constructor.
Normally constructors involve initializing the members of an object being created. In concept of inheritance, typically each class constructor in the inheritance hierarchy, is responsible for instantiating its own member variables. This makes sense because instantiation has to be done where the variables are defined.
Since an abstract class is not completely abstract (unlike interfaces), it is mix of both abstract and concrete members, and the members which are not abstract are needed to be initialized, which is done in abstract class's constructors, it is necessary to have constructors in the abstract class. Off course the abstract class's constructors can only be called from the constructors of derived class.
You are absolutely correct. We cannot instantiate an abstract class because abstract methods don't have any body i.e. implementation is not possible for abstract methods. But there may be some scenarios where you want to initialize some variables of base class.
You can do that by using base keyword as suggested by #Rodrick. In such cases, we need to use constructors in our abstract class.
You can instantiate it after you implemented all the methods. Then the constructor will be called.
I too want to make some shine on abstract surface
All answer has covered almost all the things. Still my 2 cents
abstract classes are normal classes with A few exceptions
You any client/Consumer of that class can't create object of that
class, It never means that It's constructor will never call. Its derived class can choose which constructor to call.(as depicted in some answer)
It may has abstract function.
Defining a constructor with public or internal storage class in an inheritable concrete class Thing effectively defines two methods:
A method (which I'll call InitializeThing) which acts upon this, has no return value, and can only be called from Thing's CreateThing and InitializeThing methods, and subclasses' InitializeXXX methods.
A method (which I'll call CreateThing) which returns an object of the constructor's designated type, and essentially behaves as:
Thing CreateThing(int whatever)
{
Thing result = AllocateObject<Thing>();
Thing.initializeThing(whatever);
}
Abstract classes effectively create methods of only the first form. Conceptually, there's no reason why the two "methods" described above should need to have the same access specifiers; in practice, however, there's no way to specify their accessibility differently. Note that in terms of actual implementation, at least in .NET, CreateThing isn't really implemented as a callable method, but instead represents a code sequence which gets inserted at a newThing = new Thing(23); statement.
an abstract class can have member variables that needs to be initialized,so they can be initialized in the abstract class constructor and this constructor is called when derived class object is initialized.
From https://msdn.microsoft.com/en-us/library/ms182126.aspx
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.
Since only derived classes can use an abstract class constructor then an abstract class constructor, if needed, must be declared as protected.
However, that said VS compiler will not complain (with default rules) when declaring public constructors in abstract classes however it will not allow creating a new instance.
There are two following important features that prevent to inherit Abstract class
Abstract class must have an abstract method otherwise it is not a abstract class
Abstract class must be inherited by derived class,So if a class inherited by other class than what is use of to create object of that class
Related
I have the following code in my program
public abstract class test
{
public abstract void test1();
public abstract void test2();
public abstract void test3();
}
public abstract class class1 :test
{
public override void test1()
{
string s = "";
}
}
When I change the type of my child class as abstract it build successfully and the error to include the other two methods have gone. if the child class is abstract class, no need to define at least one abstract methods?
If you mark a method as abstract it means that every (concrete) class which inherits it must provide an implementation - it's a contract in a similar way to interface implementation is a contract.
If you mark the child class as abstract also, it means that it can defer implementation to its child class(es).
It compiles fine, because the child class is abstract too.
That means that in order to instantiate an object of that type, you still need to have yet a third class (at least) that inherits from your child class and that implements the full interface (the missing abstract methods from your parent class).
The class hierarchy that you have presented, cannot be instantiated until there is a class that implements all the required methods - that would be something that can be instantiated.
No, this is not neccessary, as it's fine for an abstract class to contain just method headers, and the other method headers from the abstract base class get inherited.
No - you can declare a class abstract without having any abstract methods. It may not make any sense conceptually for an instance of that class to exist, or you may want to ensure that only subclasses of that class can be instantiated (for whatever reason)
I have following easy class design, where myObject is importing for BaseClass.
public abstract class BaseClass
{
public BaseClass(myObject parameter)
{
// ...
}
}
public class ChildClass : BaseClass
{
}
My problem is now, that I want to make my program extensible by inheriting from public BaseClass. So you could create a constructor
public ChildClass() :base(new myObject()){...}
which will lead to failures. Is there a possibilty to prevent inherited classes with own constructors? I actually would like to avoid constructors for ChildClass at all. Is this possible? Then I could use a factory and provide an Initialize method. Or is this something impossible, where I simply must be aware of and check in my code=
Classes are completely responsible for their own constructors. They aren't inherited, and every class must have a constructor. So no, there's nothing you can do to "control" what constructors a base class can or can't have.
I know we cannot create an abstract class instance, but I cannot understand why could use base invoke the constructor of the abstract class.
abstract class Fruit
{
public string Name { get; private set; }
public Fruit(string name)
{
Name = name;
}
}
class Apple : Fruit
{
public Apple(string name) : base(name) { }
}
Fruit f = new Fruit("Fruit"); // Coimple Error
Apple a = new Apple("Apple"); // Success
Dose that base keyword just invoke constructors, methods, etc?
What's the differences between create an instance and invoke a constructor?
Thanks in advance.
Only derived class (e.g. Apple) can call the constructor of its parent (abstract class) with special base word. Constructor cannot be invoked (called) directly.
I would add that the fact that an abstract class may provide a constructor doesn't mean that it's not yet abstract.
By definition, an abstract class is a class where some or none of its members don't provide a default implementation, and derived classes must provide an implementation to these members. In the other hand, since an abstract class has some of its members as just signatures - the whole abstract members -, code mustn't be able to instantiate that class.
But if a derived class - either abstract or concrete - couldn't be able to call a base abstract class constructor, abstract classes would lack polymorphic constructors and there may be no way to initialize class properties or define a default class initialization code, even if that code calls an abstract method or property.
This is why a derived class can call a parent class constructor, even if the class is abstract!
What's the differences between create an instance and invoke a
constructor?
We might try to address this question with a deep explanation with low-level details, but
I feel that it's more a conceptual issue rather than a low-level thing.
If you want a summary, calling the constructor is a part of class instantiation process. It's a method which is called once the instance has been created and initializes the instances with custom code before any other code might use that instance.
When you use base keyword in a constructor to call parent's class one, you're just chaining constructor calls from the most derived class to the base class.
Does that base keyword just invoke constructors, methods, etc?
No, use it anytime you want to explicitly invoke the parent class' methods and avoid invoking a override in the derived class. Though : base(...) syntax is exclusive to constructors, usually you would call base.method();
What are the differences between create an instance and invoke a constructor?
Creating an instance with the new operator does a number of things:
Allocates memory for the object
Initialises fields
Then finally the constructor is invoked, which will invoke base constructor first if specified.
A more in-depth explanation of the order is in this answer: https://stackoverflow.com/a/1882778/360211 but that should be enough to explain the difference.
Creating an instance with the new keyword creates a new object and returns a reference to the object.Invoking the constructor with the base keyword won't create a reference to the object(neither it will create an actual object), it will simply execute the code in the constructor.
Take a deep look onto this answer to for more information https://stackoverflow.com/a/14453366/3789232
I read an article from some site and in that article i read this :
Abstract classes can add more functionality without destroying the child classes that were using the old version. In an interface, creation of additional functions will have an effect on its child classes, due to the necessary implementation of interface methods to classes.
I don't understand what it means. Can anyone explain this more specifically , with a Good Example ?
this is the article which i read Link
Because interfaces only define members that types must implement, adding any new member to an interface will break any class that implements the old version because it inherently doesn't implement the new member. Any time you change the definition of an interface you must change every single class that implements that interface. Adding an abstract member to an abstract class does the same for derived classes but if you add a virtual member to the abstract class then it will have no impact on derived classes. They can be changed to override that member but they don't have to.
What it means is that if you consider a Abstract Class called Phone
and it has 3 virtual functions i.e.
AddPhonePrice , AddAccessoryPrice, AddAuxillaryPrice
and if there are two child classes
1) SamsungPhone 2) Iphone
now SamsungPhone will have implementation for all 3 functions.
while Iphone will have implementation for only AddPhonePrice, since they dont provide anything else with the phone
if we make interface called IMainPhone with
AddPhonePrice , AddAccessoryPrice, AddAuxillaryPrice functions
then both SamsungPhone and Iphone will need to implement all 3 functions
irrespective of whether they need them or not.
This means that you are able to add new members (methods, properties, fields, ...) to abstract classes that do not lead to changes in the derived classes - as long as the members are not abstract this is correct. For instance, consider this example:
internal abstract class MyBaseClass
{
public abstract void DoSomething();
// This method can also be added later without having an effect on the derived classes
public virtual void DoSomethingElse()
{
// Do something else...
}
}
internal class MyDerivedClass : MyBaseClass
{
public override void DoSomething()
{
// Do something...
}
}
In this case, the derived class has to implement the method DoSomething. But you can add non-abstract functions to the abstract base class later on. However, as soon as you add another abstract member to the base class, this also affects all non-abstract derived classes because the must implement the new members.
An interface on the other hand does not define concrete implementations at all but does only contain the abstract signature that all implementors must provide. Therefore, if you add a new member (method, property) to an interface it forces all implementors of the interface to also provide an implementation of the new members.
Interface: When you add a method to the base interface class, then you have to (manually) make sure all of the derived classes implement that method.
Abstract Base: When you add a method to an abstract base class, you aren't required by the compiler to implement that method in the derived classes.
I have a base class and several subclasses derived from that base class. I also have a static function in the base class that takes some parameters, and instantiates and returns an appropriate subclass based on input parameters ( my factory method.)
Now here's my problem: I want to ONLY allow instantiation of the subclasses FROM the factory method. But if I set the constructors of the subclasses to be protected, the base class can't see them. Is there an access modifier I'm missing that would allow the base class to call the subclasses constructors, but not not allow any other classes to call them?
Internal doesn't look like it will work either...I want to limit access to the subclass constructors to just the base class, there are other classes in the same assembly that should be able to access the base factory method and but not directly instantiate any of the subclasses.
Hopefully there's something really simple I'm missing...
Example:
public class Base
{
public Base CreateChild(string childType)
{
if(childType == "A")
return new ChildA();
if(childType == "B")
return new ChildB();
return null;
}
}
public class ChildA
{
protected ChildA() // This doesn't work, since now base class can't call this!
{
}
}
public class ChildB
{
protected ChildB()
{
}
}
You can declare the child classes as private nested classes inside Base
Have you tried declaring the child classes within the base class?
public class Base {
protected class ChildA {}
protected class ChildB {}
}
If accessing any derived object through the base type is a valid scenario (let's say derived types only override base implementations and do not add new functionality) then the proposed solution of making the derived types nested private classes (as previous answers propose) is the best solution.
If that's not the case then I think you are falling into a case of unjustified complexity. What is the reason why code from your same assembly can not access ChildA and ChildB constructors? It is after all code you can control, so you can always choose to make / enforce via code review that he initalization is through the factory method.
I understand there is valid reasons to not let external assemblies freely instantiate objects except through a tightly controlled mechanism. In this case just marking the constructors as internal would do.
Otherwise, I'm not sure you can achieve what you are pretending without creating a specific assembly just for this base class and its derived classes. There is definitely no access modifier that would make a static method in a derived class only visible from it's base class.