Interfaces versus Abstract Classes


In this chapter you've seen how you can create both interfaces and abstract classes (without members for now — you get to them in the next chapter). The two types are similar in a number of ways, and it is worth taking a look at this to see how to determine when you would want to use one technique or the other.

First, the similarities: both abstract classes and interfaces may contain members that can be inherited by a derived class. Neither interfaces nor abstract classes may be directly instantiated, but you can declare variables of these types. If you do so, you can use polymorphism to assign objects that inherit from these types to variables of these types. In both cases, you can then use the members of these types through these variables, although you don't have direct access to the other members of the derived object.

And now, the differences: derived classes may only inherit from a single base class, which means that only a single abstract class may be inherited directly (although it is possible for a chain of inheritance to include multiple abstract classes). Conversely, classes may use as many interfaces as they wish. However, this doesn't make a massive difference — similar results can be achieved in either case. It's just that the interface way of doing things is slightly different.

Abstract classes may possess both abstract members (these have no code body and must be implemented in the derived class unless the derived class is itself abstract) and nonabstract members (these possess a code body, and can be virtual so that they may be overridden in the derived class). Interface members, on the other hand, must all be implemented on the class that uses the interface — they do not possess code bodies. Also, interface members are by definition public (because they are intended for external use), but members of abstract classes may also be private (as long as they aren't abstract), protected, internal, or protected internal (where protected internal members are accessible only from code within the application or from a derived class). In addition, interfaces can't contain fields, constructors, destructors, static members, or constants.

Note

This indicates that the two types are intended for different purposes. Abstract classes are intended for use as the base class for families of objects that share certain central characteristics, such as a common purpose and structure. Interfaces are intended for use by classes that might differ on a far more fundamental level, but can still do some of the same things.

As an example, consider a family of objects representing trains. The base class, Train, contains the core definition of a train, such as wheel gauge and engine type (which could be steam, diesel, and so on). However, this class is abstract, because there is no such thing as a "generic" train. To create an "actual" train you need to add characteristics specific to that train. To do this you derive classes such as PassengerTrain, FreightTrain, and 424DoubleBogey, as shown in Figure 9-14.

image from book
Figure 9-14

A family of car objects might be defined in the same way, with an abstract base class of Car and derived classes such as Compact, SUV, and PickUp. Car and Train might even derive from a common base class, such as Vehicle. This is shown in Figure 9-15.

image from book
Figure 9-15

Now, some of the classes further down the hierarchy may share characteristics because of their purpose, not just because of what they are derived from. For example, PassengerTrain, Compact, SUV, and Pickup are all capable of carrying passengers, so they might possess an IPassengerCarrier interface. FreightTrain and PickUp can carry heavy loads, so they might both have an IHeavyLoadCarrier interface as well. This is illustrated in Figure 9-16.

image from book
Figure 9-16

By breaking down an object system in this way before going about assigning specifics, you can clearly see which situations should use abstract classes rather than interfaces, and vice versa. The result of this example couldn't have been achieved using only interfaces or only abstract inheritance.




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net