Interfaces

I l @ ve RuBoard

Interfaces provide a powerful abstraction to component-based development. Interfaces provide a public contract that allows components to work together. Consider an electrical wall outlet to be a receptor of a specific interface. An appliance that provides the proper plug type, the proper interface, can be used in the electrical wall outlet. The wall outlet implements one interface and the appliance implements another. Essentially, the wall outlet states that it can use any device that implements the 110-plug interface. The appliance states that it can make use of any wall outlet that implements the 110-outlet interface.

In more concrete terms, the alarm clock next to your bed implements several interfaces ”the Alarm interface, the Clock interface, and possibly the Radio interface.

Figure 2.1.2 depicts an AlarmClock component that supports an Alarm interface, a Clock interface, and a Radio interface. Figure 2.1.2 is known as a box-spoon diagram, the spoons are the lines with circles at the end sticking out of the box.

Figure 2.1.2. The AlarmClock component and supported interfaces.

graphics/0201fig02.gif

An interface is not a class and, as such, does not contain any implementation code. An interface contains members and method signatures, all of which must be public. C# allows for both a struct and a class to implement one or more interfaces. This is different from inheritance. Inheritance involves implementation from a base class, interface implementation only states that the class implementing a particular interface guarantees to fulfill the interface contract.

C# uses the interface keyword to denote the declaration of an interface, as follows :

 interface name {     body; } 

A class or struct can implement an interface by declaring the interface during declaration, as shown in the following:

 public class AlarmClock : IAlarm, IClock, IRadio { //implementation } 

NOTE

A standard naming convention for interfaces states that an interface name should begin with the capital letter I. This naming convention allows for consistency and makes it easy to spot an interface with respect to a class or struct definition.


The .NET framework makes heavy use of interfaces. In fact, to take full advantage of the services provided by .NET, understanding interface development and implementation is a must. Listing 2.1.31 implements an AlarmClock class that fulfills the interface contract shown in Figure 2.1.2.

Listing 2.1.31 The AlarmClock
 1: //File        :part02_30.cs  2: //Author    :Richard L. Weeks  3: //Purpose    :Interfaces  4:  5: using System;  6:  7: //Define the IAlarm interface  8: interface IAlarm {  9:     bool On { get; set; } 10:     void Snooze( ); 11: } 12: 13: //Define the IClock interface 14: interface IClock { 15:     void SetTime( ); 16: } 17: 18: 19: //Define the IRadio interface 20: interface IRadio { 21:     void SetStation( double station_id ); 22: } 23: 24: 25: 26: //Create an alarm clock that implements IAlarm, IClock and IRadio 27: public class AlarmClock : IAlarm, IClock, IRadio { 28: 29:     //Data members 30:     private bool    m_bOnOff; 31: 32: 33:     //The IAlarm interface implementation 34:     public bool On { get { return m_bOnOff; }  set { m_bOnOff = value; }  } 35:     public     void Snooze( ) { Console.WriteLine("IAlarm.Snooze"); } 36: 37:     //The IClock Interface 38:     public     void SetTime( ) { Console.WriteLine("IClock.SetTime"); } 39: 40:     //The IRadio interface 41:     public     void SetStation( double station_id ) { graphics/ccc.gif Console.WriteLine("IRadio.SetStation( {0}  )", station_id ); } 42: } 43: 44: 45: 46: public class InterfaceTest { 47:     public static void Main( ) { 48: 49:         AlarmClock a = new AlarmClock( ); 50: 51:         //Get the IAlarm Interface 52:         IAlarm ialarm = (IAlarm)a; 53:         ialarm.On = false; 54:         ialarm.Snooze( ); 55: 56:         //Get the IClock interface 57:         IClock iclock = (IClock)a; 58:         iclock.SetTime( ); 59: 60:         //Get the IRadio interface 61:         IRadio iradio = (IRadio)a; 62:         iradio.SetStation( 98.1 ); 63:     } 64: } 

Figure 2.1.2 has been implemented in Listing 2.1.31. The casting operator is used to obtain a requested interface, see line 52 of Listing 2.1.31. The IAlarm interface is requested from the AlarmClock instance. In the event that the AlarmClock does not support the IAlarm interface, an InvalidCastException will be thrown. If the interface does exist, a reference to the interface will be returned. As a quick aside, there are now two references to the alarm clock ”one reference for the AlarmClock variable and one reference for the IAlarm interface. Both of these references must be released before the GC will collect the AlarmClock instance.

I l @ ve RuBoard


C# and the .NET Framework. The C++ Perspective
C# and the .NET Framework
ISBN: 067232153X
EAN: 2147483647
Year: 2001
Pages: 204

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