Deep C# - Inheritance |
Written by MIke James | ||||
Monday, 27 December 2021 | ||||
Page 2 of 3
Inherited ConstructorsA special case of using the methods of the base class is the inherited constructor. A constructor is a function that creates the class and optionally initializes it. Beginners are often worried by the idea that the constructor has to “create” the class and they think that there is something they have to do to make it happen. In practice you don’t have to do anything to create an instance of the class. The system does it all for you and the constructor returns a reference to a new object with all of the properties the class defines initialized to their default values. However, if you want those properties to be initialized to something then you might have to write some code in the constructor. If you want to provide different types of initialization then you can define a number of alternative constructors, each with its own unique signature. Which constructor is used is determined by the signature of the call. All classes have one constructor with no parameters, either explicitly defined or automatically generated, which is used as the default constructor in situations where you don’t explicitly specify a constructor. If a class inherits from another class then the base class default constructor is automatically called before the child class’s own default constructor. If the base class also inherits from another class its constructor is called first and so on until we reach the first class in the inheritance chain. If a class defines an explicit constructor and inherits from another class, the explicit constructor must call one of the base class’s constructors. If the base class only has constructors that use parameters, the child class has to call one of them using the For example, suppose
then to call it you would write:
In this case the Notice that the Changing Types - CastingAs we already know, inheritance results in a type hierarchy of base classes and derived classes. We also know, see Chapter 2, that it is assumed that any derived class can stand in for its base classes, i.e. the classes it inherits from. This is such an established idea that we don’t think twice about the way that a variable can be used to reference any object of its type or derived from its type. So, in:
you can see that you can use a reference to a base class to reference a derived class without any change in syntax. This is called downcasting because the variable is supposed to reference a class higher up in the hierarchy but it actually references an object lower in the hierarchy. It is also true that a variable of a derived type can reference a base type, but in this case we do need some extra syntax. For example: MyB = (
In this case we need an explicit typecast expression, or just cast, to indicate the conversion, i.e. ( This is usually called upcasting because the variable is supposed to reference a class lower in the hierarchy than the object being assigned to it. Upcasting may be legal but what does it mean? The only sense that: MyB = (
can possibly make is if MyB = ( only works if the object we are using, i.e. what MyA references, really is a type You can see that upcasting isn’t type safe as you cannot easily work out whether what is being cast is of the correct type. For example: Random R = new Random(); This program generates no compile-time errors or warnings, but 50% of the time it fails because trying to cast an object of type |
||||
Last Updated ( Saturday, 01 January 2022 ) |