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#.
Deep C#
Buy Now From Amazon
Chapter List
- Why C#?
I Strong Typing & Type Safety
- Strong Typing
Extract Why Strong Typing
- Value & Reference
- Extract Value And Reference
- Structs & Classes
Extract Structs & Classes
- Inheritance
Extract Inheritance
- Interfaces & Multiple Inheritance
Extract Interface
- Controlling Inheritance
II Casting & Generics
- Casting - The Escape From Strong Typing
Extract Casting I
- Generics
- Advanced Generics
- Anonymous & Dynamic
Typing III Functions
- Delegates
- Multicast Delegates
- Anonymous Methods, Lambdas & Closures
IV Async
- Threading, Tasks & Locking
- The Invoke Pattern
- Async Await
- The Parallel For ***NEW!
V Data - LINQ, XML & Regular Expressions
- The LINQ Principle
- XML
- LINQ To XML
- Regular Expressions
VI Unsafe & Interop
- Interop
- COM
- Custom Attributes
- Bit Manipulation
- Advanced Structs
- Pointers
Extra Material
<ASIN:1871962714>
<ASIN:B09FTLPTP9>
Inheritance
Inheritance is a simple idea, until you try to make use of it. What's a virtual method? How do you use override and 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.
Simple Inheritance
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:
class
name:
baseclass
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:
class
MyClassA
{};
MyClassA
MyA;
doesn’t create an instance of MyClass A - only a reference variable capable of pointing to an object of type MyClass 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:
MyA
= new MyClassA();
or putting this together:
MyClassA
MyA = new MyClassA();
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 MyClass A :
Class
MyClassB : MyClassA;
then any instance of MyClass B starts out with all of the methods defined in the definition of MyClass A . This is what inheritance is all about - code reuse. If class MyClass A has a show method then so now does class MyClass B and without you having to write a single line of code.
Notice that this means that class MyClass B has two types of method - those that are defined as part of MyClass A and those that are defined within it.
If you simply want to use the inherited methods of class MyClassB you can simply use them as if they were "native" to MyClassB .
For example:
MyClassB MyB = new MyClassB();
MyB.show();
results in the show method defined in class MyClass A being called.
There is one small complication - what if the methods of class MyClassB need to call the methods defined in class MyClassA ? 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 MyClassB inherits a method “show ” from MyClassA then MyClassB can call the method using:
base.show();
In practice you can omit base as long as there is no ambiguity, i.e. if MyClass B doesn't have a show method.
|