Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# 2008 Step by Step.pdf
Скачиваний:
27
Добавлен:
25.03.2016
Размер:
14 Мб
Скачать
☆

Chapter 13 Creating Interfaces and Defining Abstract Classes

241

Interface Restrictions

The essential idea to remember is that an interface never contains any implementation. The following restrictions are natural consequences of this:

You’re not allowed to define any fields in an interface, not even static ones. A field is an implementation detail of a class or structure.

You’re not allowed to define any constructors in an interface. A constructor is also considered to be an implementation detail of a class or structure.

You’re not allowed to define a destructor in an interface. A destructor contains the statements used to destroy an object instance. (Destructors are described in Chapter 14, “Using Garbage Collection and Resource Management.”)

You cannot specify an access modifier for any method. All methods in an interface are implicitly public.

You cannot nest any types (such as enumerations, structures, classes, or interfaces) inside an interface.

An interface is not allowed to inherit from a structure or a class, although an interface can inherit from another interface. Structures and classes contain implementation; if an interface were allowed to inherit from either, it would be inheriting some implementation.

Implementing an Interface

To implement an interface, you declare a class or structure that inherits from the interface

and implements all the methods specified by the interface. For example, suppose you are defining the Mammal hierarchy shown in Chapter 12 but you need to specify that land-bound mammals provide a method named NumberOfLegs that returns as an int the number of legs

that a mammal has. (Sea-bound mammals do not implement this interface.) You could define the ILandBound interface that contains this method as follows:

interface ILandBound

{

int NumberOfLegs();

}

You could then implement this interface in the Horse class:

class Horse : ILandBound

{

...

int ILandBound.NumberOfLegs()

{

return 4;

}

}

242

Part II Understanding the C# Language

 

When you implement an interface, you must ensure that each method matches its

 

corresponding interface method exactly, according to the following rules:

 

The method names and return types match exactly.

 

Any parameters (including ref and out keyword modifiers) match exactly.

 

The method name is prefaced by the name of the interface. This is known as explicit

 

interface implementation and is a good habit to cultivate.

 

All methods implementing an interface must be publicly accessible. However, if you are

 

using explicit interface implementation, the method should not have an access qualifier.

 

If there is any difference between the interface definition and its declared implementation,

 

the class will not compile.

The Advantages of Explicit Interface Implementations

Implementing an interface explicitly can seem a little verbose, but it does offer a number of advantages that help you to write clearer, more maintainable, and more predictable code.

You can implement a method without explicitly specifying the interface name, but this can lead to some differences in the way the implementation behaves. Some of these differences can cause confusion. For example, a method defined by using explicit interface implementation cannot be declared as virtual, whereas omitting the interface name allows this behavior.

It’s possible for multiple interfaces to contain methods with the same names, return types, and parameters. If a class implements multiple interfaces with methods that have common signatures, you can use explicit interface implementation to disambiguate the method implementations. Explicit interface implementation identifies which methods in a class belong to which interface. Additionally, the methods for each interface are publicly accessible, but only through the interface itself. We will look at how to do this in the upcoming section “Referencing a Class Through Its Interface.”

In this book, I recommend implementing an interface explicitly wherever possible.

A class can extend another class and implement an interface at the same time. In this case, C# does not denote the base class and the interface by using keywords as, for example, Java does. Instead, C# uses a positional notation. The base class is named first, followed by

Chapter 13 Creating Interfaces and Defining Abstract Classes

243

a comma, followed by the interface. The following example defines Horse as a class that is a Mammal but that additionally implements the ILandBound interface:

interface ILandBound

{

...

}

class Mammal

{

...

}

class Horse : Mammal , ILandBound

{

...

}

Referencing a Class Through Its Interface

In the same way that you can reference an object by using a variable defined as a class that is higher up the hierarchy, you can reference an object by using a variable defined as an in-

terface that its class implements. Taking the preceding example, you can reference a Horse object by using an ILandBound variable, as follows:

Horse myHorse = new Horse(...);

ILandBound iMyHorse = myHorse; // legal

This works because all horses are land-bound mammals, although the converse is not true, and you cannot assign an ILandBound object to a Horse variable without casting it first.

The technique of referencing an object through an interface is useful because it enables you

to define methods that can take different types as parameters, as long as the types implement a specified interface. For example, the FindLandSpeed method shown here can take any argument that implements the ILandBound interface:

int FindLandSpeed(ILandBound landBoundMammal)

{

...

}

Note that when referencing an object through an interface, you can invoke only methods that are visible through the interface.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]