The title explains it all I believe.
In C#, I am now aware that regardless, constructors in derived classes will call a base class constructor whether it is an explicit call or an implicit default constructor. My question is why? I think it's because the derived class needs to create an object of the base class but why?
I think it's because the derived class needs to create an object of the base class but why?
An instance of a derived class is an instance of the base class. If you have a rule for what must happen when you construct an Animal, and you're constructing a Giraffe, then somehow you have to execute the rule for constructing an Animal. In C# that mechanism is "call a base class constructor".
A derived class is the base class plus extra things the derived class adds.
You still need some code that initializes the base class portion so you can add your extra parts on top. The call to the base constructor is where that initialization happens.
let's say the car is your abstract class and bmw,mazda,jeep are your driven classes.
you have fields: Name , Model,..
you have constroctor: car(),car(string model)
in car class, then when compiler doing memory allocation for object need to read abstract constructor to be aware of Name, Model.
this will call the default constructor. but you can use base("z4") to force calling overridden constructor in the abstract class.
As Scott Chamberlain said the derived class is something (plus some more features).
Of course an object can have behaviors in the constructor.
Anyway if you don't need to inherit them, you should structure your code in the right way,
you should leave base constructor empty, depends on your specific needs
Related
I have a base class Character which has several classes deriving from it. The base class has various fields and methods.
All of my derived classes use the same base class constructor, but if I don't redefine the constructor in my derived classes I get the error:
Error: Class "child class" doesn't contain a constructor which takes this number of arguments
I don't want to redefine the constructor in every derived class because if the constructor changes, I have to change it in every single class which, forgive any misunderstanding, goes against the idea of only writing code once?
You can use the following syntax to call the base class constructor from the classes that derive from it:
public DerivedClass() : base() {
// Do additional work here otherwise you can leave it empty
}
This will call the base constructor first, then it will perform any additional statements, if any, in this derived constructor.
Note that if the base constructor takes arguments you can do this:
public DerivedClass(int parameter1, string parameter2)
: base(parameter1, parameter2) {
// DerivedClass parameter types have to match base class types
// Do additional work here otherwise you can leave it empty
}
You can find more information about constructors in the following page:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors
In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly.
You do have to redeclare constructors, because they're effectively not inherited. It makes sense if you think of constructors as being a bit like static methods in some respects.
In particular, you wouldn't want all constructors to be automatically inherited - after all, that would mean that every class would have a parameterless constructor, as object itself does.
If you just want to call the base class constructor though, you don't need to write any code in the body of the constructor - just pass the arguments up to the base class as per Waleed's post.
If your base class starts requiring more information, it's natural that you should have to change all derived classes - and indeed anything calling the constructors of those classes - because they have to provide the information. I know it can seem like a pain, but it's just a natural consequence of what constructors do.
I had the same problem, and I solved it by replacing my constructor with a factory method like this:
A is the parent class.
public static T getChild<T>(int number) where T:A, new()
{
T child = new T();
T._number = number;
return child;
}
You can create a Child class with
Child b = A.getChild<Child>(2);
A kind of alternative could be to rely on a Dependency Injection container to initialize your objects, that way the that reference to the base class (could be the call to the base constructor or another initializer method) would "externalized" to the DI container.
I don't know if it makes sense to your case or not
I know and read about abstract class and interface but one point I never understood is that, what is the use of class which cannot be instantiated.
I can use normal class and virtual method instead of abstract class?
what will happen when I instantiate base class?
You typically use an abstract class when you have some set of common functionality to be shared between derived classes. That is, you cannot use an interface because you want to provide some default functionality.
Take a look at the System.IO.Stream class. This class provides some common base functionality, but requires that specific types of streams implement some members in order for it to function. These members are also tagged abstract, which indicates to the compiler and runtime that there is no suitable base-class implementation. A non-abstract class that derives an abstract class must override all inherited abstract members, just like a class that implements an interface must implement all members defined on the interface.
In the stream example, the Read() method is abstract, but the ReadByte() method is not -- because ReadByte() can be implemented in terms of a call to Read(). (Although not optimally, which is why ReadByte() is virtual, so that a more efficient implementation can optionally be provided.) Virtual members are different, because they do have an implementation, but can optionally be overridden. Abstract members have no implementation by default, and must be overridden.
In other words, methods on an abstract class can use other abstract members on the class, even though they have no implementation! This is because a derived non-abstract class is required to provide an implementation -- an implementation is guaranteed to exist at the point that the method is invoked. This is analogous to how you can use members of an interface even though the members have no implementation on the interface, because it's guaranteed that an object implementing the interface must implement all of its members.
Subclasses like MemoryStream and FileStream override all of the abstract methods to form a concrete class, and they can be instantiated. However, you are able to store them in a Stream reference variable and treat them like a generic "black box" stream. This allows you to declare a method that accepts a Stream object, and you don't have to care what kind of stream it actually is.
Stream foo = new Stream(); // Invalid, Stream is abstract.
Stream foo = new MemoryStream(); // Valid.
So, now to summarize the answers to the questions you posed in your title. An abstract class cannot be instantiated because it may contain members that are abstract and have no implementation. The use of an abstract class is twofold: first, to be subclassed and allow the subclasses to share a common implementation of some members, and second, to allow instances of any objects of subclasses to be used through references to the abstract class.
Abstract classes are very useful and it's all about design. If, for example, you have an abstract base class called Shape, which has functions such as 'Draw' and 'Move'. You then inherit the Shape class to create a 'Circle' class and 'Square' class.
The inherited classes both have the functions Draw and Move. Move may have functionality in the base class which the child classes use, but draw functionality is handled by each child.
While you then instantiate a Circle and Square, it is meaningless to have just a 'Shape' object.
Hope that helps.
Abstract and interfaces enable you to share some common logic but you can't instantiate, directlym any of them
To add to cdhowie answer the most relevant differences between interfaces and abstract classes are:
Inheriting from an abstract class forces child classes to be compromised with a chain of hierarchy. With interface different classes implementing it are completely loose from each other.
With abstract classes you can have methods or properties with logic, that is, some code is implemented itself in the abstract class. In interface there is no code or logic thus forcing implementors to write all the logic
Abstract class and interface class are language features both offering some compile time rules and some run time rules aiding design. So far instantiating abstract class or interface class goes, its not possible using the compiler for sure, if one were to program using assembly language for C++ or say intermediate language code/byte code for C# or Java it might be possible to instantiate them as well, I am not sure on this point though. Since at run time there is a type object for both abstract class and interface class.
Should I always annotate a class which has only protected constructors by design with abstract keyword? Why?
Let’s suppose the class does not have abstract members.
If no, could you give some examples?
No. A type with only protected constructors is still creatable - either through a static factory method on the type, or via reflection (including, as one option, totally skipping the constructors).
An abstract type is never creatable.
Mark the type as abstract: if it is abstract. So: does it make sense for an object of that type (rather than a subclass) to exist?
No, you should not do this by design since thats not what abstract classes are made for.
abstract on MSDN
In my opinion, an abstract class is used to represent a bunch of classes which are of same type in logical view. It means that this bunch of classes are common in either properties or behaviours. It is not used to represent the class which has a 'Private' constructor and can not be created outside the class itself.
How do you programmatically find out if the ctor of a class invoked its base class ctor and with what arguments?
A derived class constructor always calls a base class constructor. This is required by the C# language specification.
To find out what arguments are passed, you might be able to ask the base class, if it saved them, but there is no universal way to do it.
Finding out which base class constructor got called is impossible for all code I've ever seen. The base class would have to save that information explicitly, but typically different constructors just use default values for some internal data.
When you derive from a class and instance the subclass, the runtime also instances the super class, right?
Since abstract classes can't be instanced, are they not created by the runtime when a subclass is instanced?
If so, then abstract class inheritance would be faster than normal class instance?
The runtime never creates separate instances of the base class and the derived class - it's just that the derived class instance also has all the variables etc of the base class, and runs the base class constructor as part of initialization. There's no difference here between "normal" base classes and abstract base classes.
I think you have some details confused.
When you construct an object, where the class of that object inherits from another class, it's not like you get two objects in memory.
You only get one, but it has space set aside for fields that comes from both.
Put another way, if the original class needs 10 bytes to hold its fields, and your inherited class needs 5 bytes to hold its specific fields, when you construct an object from your inherited class, it would occupy 15 bytes, where the first 10 corresponds to the fields from the base class. (note, this is a very simplified explanation, there's a lot more going on that dictates the actual size of objects).