Multiple Implementation in C#
By Craig Breakspear
Can you inherit from multiple classes in C#? Simply put, this cannot be done. However there are ways around it. From a design perspective you must ask yourself, Will a Class fully represent an object? Meaning that, if we have a base class with abstract methods designed for a particular application and we know that the inheriting object will only need the methods defined in that class. We now have a valid design pattern here.
The Vehicle Car Object
Abstract classes and methods
- If you have an abstract class, objects of that specific class almost always have no meaning.
- You create an abstract class when you want to manipulate a set of classes through its common interface.
- A class containing abstract methods is called an abstract class.
- It cannot safely create an object of an abstract class, so you get an error message from the compiler.
- If you inherit from an abstract class and you want to make objects of the new type, you must provide method definitions for all the abstract methods in the base class. If you don’t, then the derived class is also abstract.
- It’s possible to make a class abstract without including any abstract methods. you want to prevent any instances of that class.
- Making a class abstract doesn’t force you to make all the methods abstract.
- Abstract classes are also useful refactoring tolls, since they allow you to easily move common methods up the inheritance hierarchy.
Lets say we have an abstract class called "Vehicle" as well as another class called "ConstructionVehicle". The vehicle class has methods such as Accelerate() , Stop(), and the "ConstructionVehicle" class has methods such as ExecuteDump() and TurnOnBackUpSound(). If we were only going to build a Car object and know we would only use those methods from the "Automobile" class this would be fine.
- The abstract keyword allows you to create one or more undefined methods in a class.
- The interface keyword produces a completely abstract class, one that provides no implementation at all.
- The interface is used to establish a "protocol" between classes.
- It allows you to perform a variation of "multiple inheritance" by creating a class that can be upcast to more than one base type.
- An interface can also contain fields, but these are implicitly static and final.
- Once you’ve implemented an interface, that implementation becomes an ordinary class that can be extended in the regular way.
- When you implement an interface, the methods from the interface must be defined as public.
- It doesn’t matter if you are upcasting to a "regular" class, an abstract class, or to an interface.
The DumpTruck Object
- Creating a method that behaves differently depending on the argument object that you pass it is called the Strategy design pattern.
- The method contains the fixed part of the algorithm to be performed, and the Strategy contains the part that varies.
- In this approach to Adapter, the Adapter constructor takes the interface that you have, and produces an object that has the interface that you need.
Now we want to create another object called "DumpTruck". We could inherit from the Automobile class but that class does not have the methods that we need called ExecuteDump() and TurnOnBackUpSound(). If we were using a language such as C++ we could easily inherit from both classes using multiple inheritance. However, seeing C# is our language of choice, multiple inheritance is not an option, you may only inherit from one Base Class.
“Multiple inheritance” in Java
- This act of combining multiple class interfaces is called multiple inheritance.
- In Java, you can perform the same act, but only one of the classes can have an implementation.
- If you do inherit from a non-interface, you can inherit from only one. All the rest of the base elements must be interfaces.
- You can upcast to each interface, because each interface is an independent type.
- When you combine a concrete class with interfaces this way, the concrete class must come first, then the interfaces.
- To prevent the client programmer from making an object of this class and to establish that it is only an interface.
- If it’s possible to create your base class without any method definitions or member variables, you should always prefer interfaces to abstract classes.
From Abstract Classes to Interfaces
Extending an interface with inheritance
- Normally, you can use extends with only a single class, but extends can refer to multiple base interfaces when building a new interface.
From a design perspective we must choose a different design. C# supports what is called "Multiple Implementation", which is to says a class can implement more than one interface. Our design now changes the "Vehicle" class and the "ConstructionVehicle" class into interfaces. Below we have defined the two interfaces with their very simplistic methods:
Name collisions when combining Interfaces
- Using the same method names in different interfaces that are intended to be combined generally causes confusion in the readability of the code, as well.
Adapting to an interface
- 365bet在线官网，You write a method that performs certain operations, and that method takes an interface that you also specify.
- It means that a method that takes an interface provides a way for any class to be adapted to work with that method.
Fields in interfaces
- Any fields you put into an interface are automatically static and final.
- Interface is a convenient tool for creating groups of constant values.
If we built a class that inherited from these two interfaces we would be
able to do so spanning multiple inherited interfaces. Design problem
solved! Or is it?
Explicit Interface Implementation
Initializing fields in interfaces
- Fields defined in interfaces cannot be "blank finals," but they can be initialized with non-constant expressions.
- Since the fields are static, they are initialized when the class is first loaded, which happens when any of the fields are accessed for the first time.
- The fields, of course, are not part of the interface. The values are stored in the static storage area for that interface.
If you look at both interfaces defined above you'll notice that they share in common a method of the same name "TurnOnBackUpSound()". Problem? No, in fact C# supports what is known as "Explicit Interface Implementation", which allows the programmer to specify which member of which interface they want to use. Putting the Interface name in front of the member name allows this to happen as shown below.
- Implementing a private interface is a way to force the definition of the methods in that interface without adding any type information.
- An interface nested within another interface is automatically public and cannot be made private.
- When you implement an interface, you are not required to implement any interfaces nested within.
- private interfaces cannot be implemented outside of their defining classes.
public class DumpTruck: IEngine, IBody
Interfaces and factories
- A typical way to produce objects that fit the interface is the Factory Method design pattern.
- Instead of calling a constructor directly, you call a creation method on a factory object which produces an implementation of the interface.
- In this way, in theory, your code is completely isolated from the implementation of the interface, thus making it possible to transparently swap one implementation for another.
- Why would you want to add this extra level of indirection? One common reason is to create a framework.
Console.WriteLine("This is the Engine TEst",',',');
Console.WriteLine("This is the Body TEst",',',');
- Almost anytime you create a class, you could instead create an interface and a factory.
- Any abstraction should be motivated by a real need.
- An appropriate guideline is to prefer classes to interfaces.
- Start with classes, and if it becomes clear that interfaces are necessary, then refactor.
Another benefit to this technique is something called "Implementation Hiding". Implementation Hiding allows the methods from the implemented interface to be hidden from the derived class unless the developer explicitly calls the interface. This technique obviously reduces the clutter for a developer.