Motivation
Inheritance provides another very useful
mechanism: (subtype)
polymorphism.
In a nutshell, the idea is that if a Pyramid
1 class extends the
Rectangle
class, then a Pyramid
object can still access all the
Rectangle
’s public methods, properties and attributes. Indeed, a
Pyramid
is a Rectangle
: this is precisely what polymorphism means.
While the example below is abstract, it can be easily instantiated to
e.g., a Cat
class inheriting from a Pet
class or a Pyramid
class
inheriting from a Rectangle
class.
Inheriting Attributes, Properties and Methods
Consider the following two classes:
Then,
- Any
Class1
object has an attributeattribute1
, a propertyProperty1
and a methodSetAttribute1
. - Any
Class2
object has the attribute, property and method of aClass1
object, and in addition, it has aProperty2
property.
This means that the following code is valid:
Note, however, that object1.Property2 = "Test";
would not compile,
since an object from Class1
cannot access the attributes, properties
and methods of Class2
. Stated differently, an object in Class2
is
a(n object in) Class1
, but the converse is not true: an object in
Class1
is not an object in Class2
.
Polymorphism and References
Note that a Class1
object can be created using a Class2
constructor,
since an object in Class2
is a(n object in) Class1
. Formally, we
can write:
and then manipulate object3
like any other *object from Class1
(it
is, in a way, “truncated”). In particular, we can use
but object3.Property2 = "Test";
would not compile *since we would be
trying to access a property of Class2
with a Class1
object. Remember
that an object in Class1
*is not* an object in Class2
, and that the
way we declared it, object3
is a Class1
object.
Solving Ambiguity by Overriding
For Methods
Now, consider the following class implementation and usage:
Console.WriteLine(object1.Test());
will display “Class1”: there is no
ambiguity, since object1
is a Class1
object, it can access only the
methods in its class.
However, the situation is less clear for
Console.WriteLine(object2.Test());
: since object2
is “at the same
time” a Class1
and a Class2
object, which method will be called? In
this case, “Class2” will be displayed since C# prefers the “closest”
method available (that is, the one in the same class as the calling
object). However, a warning will be issued by the compiler because the
Test
method in Class2
“hides” the inherited method Test
from
Class1
.
A much better code explicitly instructs C# to override Class1
’s
Test
method with Class2
’s Test
method. However, this further
requires Class1
’s Test
method to explicitly give permission to be
overriden, using the virtual
keyword:
This program will also display, as expected,
but this time the compiler will not complain: there is no ambiguity, as
Class2
’s Test
method must explicitly take precedence when an object
in Class2
is calling a Test
method.
Note that by default, methods are non-virtual, and non-virtual method
cannot be overridden. However, overriding methods are treated as virtual
and can be overridden themselves, unless they use the sealed
keyword,
as follows:
Such a method cannot be overridden by classes inheriting from the class to which they belong.
Last but not least, note that an override method must have the same signature as the overridden method.
For Attributes and Properties
Virtual attributes and properties can similarly be overridden, provided
of course the overriding property or attribute has the same datatype and
name as the virtual method or property. Consider for instance an int
Property
in a Class1
class with no requirement that is inherited by
a Class2
that wish to forbid negative values. One could do the
following:
Note that the property in Class2
has a backing field while there is no
need for it in Class1
.
The following would then throw an exception when the
object2.Property = -12;
statement would be executed:
Note that, as for methods, overriding properties are by default virtual and can be overridden, for example as follows:
Footnotes
-
Technically, a “rectangular pyramid”, if we require the pyramid to have a rectangle as its base. ↩