CHAPTER 8 WORKING WITH INTERFACES
When you run this application, the class name of each class prints out to the console, via the
GetType() method you inherit from System.Object. As explained in Chapter 15, this method (and .NET
reflection services) allow you to understand the composition of any type at runtime. In any case, the
output of the previous program is shown next:
***** A First Look at Interfaces *****
Your clone is a: String
Your clone is a: OperatingSystem
Your clone is a: SqlConnection
Another limitation of abstract base classes is that each derived type must contend with the set of
abstract members and provide an implementation. To see this problem, recall the shapes hierarchy we
defined in Chapter 6. Assume we defined a new abstract method in the Shape base class named
GetNumberOfPoints(), which allows derived types to return the number of points required to render the
shape:
abstract class Shape
{
...
// Every derived class must now support this method!
public abstract byte GetNumberOfPoints();
}
Clearly, the only class that has any points in the first place is Hexagon. However, with this update,
every derived class (Circle, Hexagon, and ThreeDCircle) must now provide a concrete implementation of
this function, even if it makes no sense to do so. Again, the interface type provides a solution. If you
define an interface that represents the behavior of “having points,” you can simply plug it into the
Hexagon type, leaving Circle and ThreeDCircle untouched.
Source Code The ICloneableExample project is located under the Chapter 8 subdirectory.
Defining Custom Interfaces
Now that you better understand the overall role of interface types, let’s see an example of defining and
implementing custom interfaces. To begin, create a brand-new Console Application named
CustomInterface. Using the Project Add Existing Item menu option, insert the file(s) containing your
shape type definitions (Shape.cs and DerivedShapes.cs in the book’s solution code) created back in
Chapter 6 during the Shapes example. After you have done so, rename the namespace that defines your
shape-centric types to CustomInterface (simply to avoid having to import namespace definitions in your
new project):
namespace CustomInterface
{
// Your shape types defined here...
}
284