Deep C# - Interface
Written by Mike James   
Tuesday, 12 April 2022
Article Index
Deep C# - Interface
Multiple Inheritance
The Diamond Problem

Interfaces - what are they for? Not quite inheritance yet they seem to fit the same purpose. Find out in this extract from my new book, Deep C#: Dive Into Modern C#.

Deep C#

 Buy Now From Amazon

DeepCsharp360

 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
       Extract 
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
       Extract
    Structs & Classes 
  6. Inheritance
      
    Extract
    Inheritance
  7. Interfaces & Multiple Inheritance
      
    Extract Interface ***NEW!
  8. Controlling Inheritance

    II Casting & Generics
  9. Casting - The Escape From Strong Typing
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic

    Typing
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures

    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For

    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions

    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material

 

 <ASIN:1871962714>

 <ASIN:B09FTLPTP9>

Interfaces & Multiple Inheritance

In the previous chapter we discovered that code reuse is no longer the main concern of object-oriented programming – type safety is. With this in mind the idea of an interface becomes very obvious as a way of ensuring type safety and even allowing a form of multiple inheritance.

One problem with C#’s implementation of the interface idea is that, while it started out simple and with a single clear objective, over time features have been added which make it more confusing. When to use an interface is no longer as clear as it was as now an interface is much more like an abstract class. Many of the extensions to the basic interface idea introduced are practically useful, but theoretically muddled. The concept of interface has slowly been drifting back toward that of class, but with seemingly arbitrary restrictions on what you can do. It can be confusing, but there is reason behind it all.

The Basic Interface

Superficially an interface is like a class in that it can be inherited. The C# syntax is even very similar. For example, to define an interface with a single method you would write:

public interface IMyInterface
{
 	void myMethod(int value);
}

An interface can only define methods, properties, indexers and events, but not raw fields, and in it purest form it contains no implementation of any of these. IMyInterface looks like a class and indeed it can be inherited.

For example:

public class MyClass:IMyInterface{}

This looks a lot like simple inheritance, but, and this is the important difference, MyClass doesn’t have to inherit any implementation details from IMyInterface. That is, if you try to create a MyClass object without doing anything about IMyInterface:

MyClass MyObject = new MyClass();

you will see a compile-time error.

You can’t create MyObject unless you write some code that implements all of the methods defined in the interface. That is, to make the previous example work you would have to define MyClass as:

public class MyClass:IMyInterface{
 	void IMyInterface.myMethod(int value)
 	{
  		code that does something
 	}
}

You don’t have to specify the interface method as IMyInterface.myMethod if there isn’t any chance of a name clash, but it’s a good habit to get into.

In this case it looks as if myMethod is being overridden by a new definition provided by IMyInterface.myMethod. This isn’t really true as there is no implementation of myMethod provided for you to override.

To be clear:

 

  • A class that inherits from an interface doesn’t usually inherit any methods, only method declarations.

 

The reason for “usually” will be explained later, see default implementations.

What good does this do?

An interface is very similar to the idea of a pure abstract class. If you declare a class as abstract then any methods that are also declared as abstract don’t have definitions and have to be overridden by any class that inherits the abstract class – unless it too is declared to be abstract. An abstract class can’t be used to create objects and it only becomes “non-abstract” when all of the abstract methods have been overridden.

You can see that abstract classes allow the definition of an inheritance chain that adds more implementation code at each step. The role of an abstract class is to represent the most abstract object in the hierarchy, perhaps so abstract that implementations of the methods it defines wouldn’t be useful but would be for derived classes.

An interface is like an abstract class but it doesn’t fit into the usual class and type hierarchy. The intended use of an interface is to ensure that all classes that inherit from it have the methods that it declares. If a class doesn’t implement all of the interface methods exactly then the class doesn’t compile. You can think of it as a template for a class and its use is to ensure that classes present a uniform and enforced set of methods that can be used with confidence by other objects. Used in this way it is a central part of most modern programming methodologies.

The interface is a promise that the class has a set of methods and hence it is about type safety and not code reuse.



Last Updated ( Tuesday, 12 April 2022 )