The course is part of this learning path
C# is a single inheritance language, meaning a class can only have one direct parent. Often single inheritance can be a limiting factor or obstacle when designing an application's class hierarchy. This course explores how C# interfaces mimick multiple inheritance, enabling a class to take on the properties and methods of other unrelated classes.
This course is intended for anyone who wants to take their C# object-oriented programming to the next level..
To get the most out of this course, you should have a basic understanding of C# classes. If you are unfamiliar with C# classes, please take our Introduction to object orientation and C# Class course first.
The source code used in this course is available at https://github.com/cloudacademy/csharp-interfaces.
One of the key features of object orientation is inheritance. Inheritance is where one class is derived from another, so can be thought of as a child of the first class and, as such, can inherit the properties or methods of its parent. A typical example is an employee class inheriting from a person class. The employee inherits properties like first name, last name, date of birth, etc. The employee class adds properties like start date and job title. Inheritance works well and is intuitive when the objects they represent share properties and methods in a way that makes sense. Inheritance tends to go awry when dealing with class taxonomies involving many classes and levels of inheritance where you want some children to have methods that aren’t a good fit with their ancestors.
You could have manager and worker classes, Inheriting from employee. Under each of those, there could be several more hierarchy levels for different job types and then classes related to specific job titles under each of those. Your company has specialized staff that work at the Department of Defense Area 51 facility. Employee classes on assignment to Area 51 need a whole bunch of methods ranging from security, psychometrics, and biometrics that aren’t relevant or necessary for typical employees. Staff assigned to Area 51 come from all over the employee hierarchy, so there is no single line of inheritance where you can add these specialist methods. There are several strategies for tackling this situation in the domain of single inheritance languages, to which C# belongs. You can put virtual or abstract methods representing the ones you want to implement in the children into their common ancestor.
There are two issues with this approach. One, you’ve got methods, even though virtual, that bear no relationship with the ancestor class. You’ve put methods and properties into classes just so they are available in some of the children. If you use abstract methods, you’ll need to implement them in the children, and while you can have code in virtual methods, the chances are that implementation in the ancestor will have to be overridden in the children. I liken this scenario to packing to go on holiday, where you don’t know exactly what the weather will be, so you take your whole wardrobe, only to end up wearing a T-shirt and shorts. A core principle of object orientation is having classes designed to meet specific needs. Excessively adding methods to a class so its descendants can implement them isn’t ideal. Because you don’t want or need the Area 51 methods implemented in standard employee classes, you derive Area 51 specific classes. Job titles 51 are shown hanging off the bottom of the hierarchy, but you could equally have Area 51 derivatives of classes further up the hierarchy. However, this will propagate duplication, as we shall see.
Hence, a Janitor51 class descended from Janitor that implements the Area 51 methods. Alternatively, you could mirror the employee hierarchy with a root class called Employee51 or insert Employee51 after the employee root. All the children will inherit the Area 51 methods, but now you have duplication baked into the class hierarchy, which is seldom good. In multiple inheritance languages like C++, you can inherit methods from multiple parents, but as I said, C# is single inheritance and doesn’t support that. This is where interfaces come into play.
An interface is a named set of property and method declarations without a constructor. Strictly speaking, an interface shouldn’t do anything; it’s like a placeholder representing a class. Classes don’t inherit from an interface, as there’s nothing to inherit, but they must implement all the properties and methods that an interface declares. While a C# class can have only one parent, it can implement many interfaces. When I said an interface shouldn’t do anything, prior to C# version 8, an interface didn’t. However, this employee scenario would mean writing code for all the declared interface methods in each class implementing the interface. I’ve always found this aspect of interfaces less than ideal, and it turns out I wasn’t alone. Default interface methods are interface method declarations with code. It turns out, for all intents and purposes, C# does have a form of multiple, albeit optional, inheritance. You can create an interface with the methods you need, including default code that will be executed if the class implementing the interface doesn’t implement all of the methods.
Hallam is a software architect with over 20 years experience across a wide range of industries. He began his software career as a Delphi/Interbase disciple but changed his allegiance to Microsoft with its deep and broad ecosystem. While Hallam has designed and crafted custom software utilizing web, mobile and desktop technologies, good quality reliable data is the key to a successful solution. The challenge of quickly turning data into useful information for digestion by humans and machines has led Hallam to specialize in database design and process automation. Showing customers how leverage new technology to change and improve their business processes is one of the key drivers keeping Hallam coming back to the keyboard.