Page 1 of 3
Inheritance - is it where it all goes wrong? Find out in this extract from my new book, Deep C#: Dive Into Modern C#.
Buy Now From Amazon
- Why C#?
I Strong Typing & Type Safety
- Strong Typing
Extract Why Strong Typing
- Value & Reference
- Extract Value And Reference
- Structs & Classes
Extract Structs & Classes
- Interfaces & Multiple Inheritance
Extract Interface ***NEW!
- Controlling Inheritance
II Casting & Generics
- Casting - The Escape From Strong Typing
- Advanced Generics
- Anonymous & Dynamic
Typing III Functions
- Multicast Delegates
- Anonymous Methods, Lambdas & Closures
- Threading, Tasks & Locking
- The Invoke Pattern
- Async Await
- The Parallel For
V Data - LINQ, XML & Regular Expressions
- The LINQ Principle
- LINQ To XML
- Regular Expressions
VI Unsafe & Interop
- Custom Attributes
- Bit Manipulation
- Advanced Structs
Inheritance is a simple idea, until you try to make use of it. What's a virtual method? How do you use
new? It’s tricky when you look at the details. There are also all of the philosophical issues about what makes good maintainable code. In this chapter we look at the basics of inheritance and the subtle corners of the idea.
C#’s inheritance mechanisms are particularly clean and easy, but let’s make sure that we know how they work.
The fundamental class declaration in C# takes the form:
If you don’t specify a base class then the default class called
object is used.
Only a class can inherit and only from another class – structs always inherit from
object and can’t be used to create new structs or classes by inheritance. If you want to create a class that can’t be used as a base class for a new class then simply add the
sealed modifier to the start of the class definition – see Chapter 7.
Notice that C# only allows single inheritance which, by contrast to C++ and Python, is something of a relief! If you think that C++’s ability to create classes from more than one base class is a good idea then you haven’t seen some of the stranger things that can happen when this powerful facility gets out of hand. The preferred approach to multiple inheritance is to make use of interfaces which define the type of what is to be inherited without supplying an implementation. There is no doubt that single inheritance is safer and can do everything that multiple inheritance can if you are prepared to approach it in the right way and do some additional work.
Variable Type and Object Type
As we have already seen, when you create an instance of a class you first create a reference variable of the correct type. For example:
doesn’t create an instance of
A - only a reference variable capable of pointing to an object of type
A. You have to be careful how you phrase such ‘pointing to an object’ because C# doesn’t have pointers as such.
After declaring a reference variable you can set it to point to, or reference, a new instance of the class using:
or putting this together:
MyA = new
Notice that there are two things going on here – the type of the variable making the reference and the type of the object it references. In a simple world these would always be the same.
If you now create a class that inherits from
then any instance of
B starts out with all of the methods defined in the definition of
A. This is what inheritance is all about - code reuse. If class
A has a
show method then so now does class
B and without you having to write a single line of code.
Notice that this means that class
B has two types of method - those that are defined as part of
A and those that are defined within it.
If you simply want to use the inherited methods of class
you can simply use them as if they were "native" to
MyB = new
results in the
show method defined in class
A being called.
There is one small complication - what if the methods of class
need to call the methods defined in class
? One of the advantages of single inheritance is that if you want to call the base class’s methods you can do so with a single keyword
base because you don't have to specify which base class is to be used as there is only one. For example, if
inherits a method “
can call the method using:
In practice you can omit
base as long as there is no ambiguity, i.e. if
B doesn't have a