Interfaces


An interface is a contract and defines the requisite behavior of generalization of types. For example, vehicle behavior includes ignition on, ignition off, turn left, turn right, accelerate, and decelerate. A car, truck, bus, and motorcycle are included in the vehicle category. As such, they must encapsulate baseline behavior representative of all vehicles. The vehicle interface defines that baseline. Specific vehicle types implement that baseline behavior differently than others. A car accelerates differently from a motorcycle. A motorcycle turns differently from a bus. An interface mandates a set of behaviors, but not the implementation. The derived type is free to implement the interface in an appropriate manner. Interfaces must be inherited. You cannot create an instance of an interface.

Any class or structure that inherits an interface commits to implementing the members of that interface. An interface is an array of related functions that must be implemented in a derived type. Members of an interface are implicitly public and abstract.

An interface is similar to an abstract class. Both types must be inherited. You cannot create an instance of either. Abstract members require implementation in the derived type. Interface members require implementation in a derived type. Although abstract and interface members are similar, there are several differences:

  • An abstract class can contain some implementation. Interfaces have no implementation.

  • Abstract classes can inherit other classes and interfaces. Interfaces can only inherit other interfaces.

  • Abstract classes can contain fields. Interfaces cannot have state.

  • Abstract classes have constructors and destructors. Interfaces have neither.

  • Interfaces can be inherited by structures. Abstract classes are not inheritable by structures.

  • Interfaces support multiple inheritance. Abstract classes support single inheritance.

When choosing between defining an interface versus an abstract class that has all abstract members, select the interface. With an interface, you can still inherit other types. Further-more, interfaces are clearer. The ZClass in the following code is simply not as clear as a comparable interface:

 public abstract class ZClass {     abstract public void MethodA (int a);     abstract public void MethodB (int a);     abstract public void MethodC (int a);     abstract public void MethodD (int a); } public interface IZ {     void MethodA (int a);     void MethodB (int a);     void MethodC (int a);     void MethodD (int a); } 

This is the syntax of an interface:

 attributes accessibility modifiers interface interfacename :baselist    {interface body } 

An interface can begin with an attribute. Use attributes to further describe an interface, such as the ObsoleteAttribute. For accessibility, independent interfaces can be public or internal. Nested interfaces can also be protected or private. Interfaces can be nested in classes and structs, but not in other interfaces. Interfaces support the unsafe modifier. For nested interfaces, the new modifier is also applicable. Baselist is a list of zero or more interfaces that this interface inherits. The interface body contains the members of the interface, which consists of methods, properties, indexers, and events. As mentioned, interface members are implicitly public and abstract.

Interfaces can inherit from other interfaces. The inherited members are added to the members of the current interface. The inherited interface essentially extends the current interface. A type inheriting the interface must implement the aggregate interface, which includes the members of the current interface and members that interface inherited from other interfaces. If a member appears in both the current interface and an inherited interface, there is no ambiguity. An identical member in a current interface hides the same member in an inherited interface. However, a compiler warning is generated. Add the new modifier to the member in the current interface to avoid the warning.

In the following code, IZ and IY are interfaces. The IY interface inherits IZ. MethodB is a member of both interfaces. For that reason, IY.MethodB hides IZ.MethodB with the new modifier. Types implementing the IY have to implement the MethodA, MethodB, and MethodC methods. These are members of both interfaces.

 public interface IZ {     void MethodB();     void MethodC(); } public interface IY: IZ{     void MethodA();     new void MethodB(); } 

A type can inherit multiple interfaces. The type must implement the members of each interface that is inherited. Those interfaces may have identical members. For example, assume that IZ and IY interfaces contain a MethodA method. The single implementation in the derived type satisfies the requirements for both IZ.MethodA and IY.MethodA. Therefore, the same method in multiple interfaces is not ambiguous. The implementation in the type consolidates all requirements for the interface member.

Implementing Interfaces

Members of an interface are implicitly public. The implementation in the type must also be public.

In the following code, the Car class inherits the IVehicle interface. As required, the members of the IVehicle interface are implemented in the Car class.

 public interface IVehicle {     void IgnitionOn();     void IgnitionOff();     void TurnLeft();     void TurnRight(); } public class Car: IVehicle{     public void IgnitionOn(){     }     public void IgnitionOff(){     }     public virtual void TurnLeft() {     }     public virtual void TurnRight(){     } } 

A class that inherits multiple interfaces probably falls into multiple categorizations. An amphibious vehicle is a combination of a vehicle and a boat. In the following code, the Amphibious class inherits both the IVehicle and IBoat interfaces. The members of both interfaces are implemented in the Amphibious class. As discussed, duplicate interface members are implemented only once.

 using System; namespace Donis.CSharpBook {     public interface IVehicle {        void IgnitionOn();        void IgnitionOff();        void TurnLeft();        void TurnRight();     }     public interface IBoat {        void IgnitionOn();        void IgnitionOff();        void TurnLeft();        void TurnRight();        void FishFinder();        void Rudder();     }    public class Amphibious: IVehicle, IBoat {        public void IgnitionOn(){        }        public void IgnitionOff(){        }        public void TurnLeft() {        }        public void TurnRight() {        }       public void FishFinder() {       }       public void Rudder(){       }     } } 

Explicit Interface Member Implementation

You can associate the implementation of an interface member with a specific interface. This is called explicit interface member implementation. Explicit interface member implementation binds an interface member to a particular interface, which requires prefixing the member with the interface name. Members implemented in this manner are not accessible through the derived type. For this reason, the accessibility modifier is omitted from explicitly implemented interface member. These members are available only via an interface cast. The modifiers abstract, virtual, override, or static are also not allowed.

In the following code, the ZClass inherits the IA interface. The IA.MethodA is an explicitly implemented interface member, whereas IA.MethodB is implemented regularly. Because it is explicitly implemented, MethodA is prefixed with the interface name. Because the implementation of MethodA is hidden, it cannot be called from a ZClass instance type. However, you can cast the instance to the underlying interface, which is interface IA. The method can then be called on that interface.

 public class Starter{     public static void Main(){         ZClass obj=new ZClass();         obj.MethodA(); // Error         obj.MethodB();         IA i=obj;         i.MethodA();     } } public interface IA {    void MethodA();    void MethodB(); } public class ZClass: IA {     void IA.MethodA() {         Console.WriteLine("IA.MethodA");     }     public void MethodB() {         Console.WriteLine("IA.MethodB");     } } 

Explicit interface implementation is most helpful when duplicate members require separate implementations. Members inherited from multiple interfaces might require separate implementation. Normally, they are consolidated with a single implementation. Another possibility is duplicate members between the interface and derived type. You can implement duplicate members separately with explicit interface implementation. Explicit interface implementation provides separate implementation without ambiguity.

The following code is for the amphibious vehicle. Steering a boat is different from steering a car. Therefore, TurnLeft and TurnRight are explicitly implemented for the IBoat interface. TurnLeft and TurnRight are also implemented explicitly for the IVehicle interface. To assign defaults, Amphibious delegates to IVehicle.TurnLeft and IVehicle.TurnRight from identical functions in the class.

 using System; namespace Donis.CSharpBook {     public class Starter{         public static void Main(){             Amphibious marinevehicle=new                     Amphibious();             marinevehicle.IgnitionOn();             marinevehicle.TurnLeft();             IBoat boatmaneuvers=marinevehicle;             boatmaneuvers.TurnLeft();             marinevehicle.IgnitionOff();         }     }     public interface IVehicle {        void IgnitionOn();        void IgnitionOff();        void TurnLeft();        void TurnRight();     }     public interface IBoat {        void IgnitionOn();        void IgnitionOff();        void TurnLeft();        void TurnRight();        void FishFinder();        void Rudder();     }     public class Amphibious: IVehicle, IBoat {        public void IgnitionOn(){            Console.WriteLine("Ignition on.");        }        public void IgnitionOff(){            Console.WriteLine("Ignition off.");        }        public void TurnLeft() {            IVehicle vehicle=this;            vehicle.TurnLeft();        }        public void TurnRight() {            IVehicle vehicle=this;            vehicle.TurnRight();        }        void IVehicle.TurnLeft() {            Console.WriteLine("Turn vehicle left.");        }        void IVehicle.TurnRight() {            Console.WriteLine("Turn vehicle right.");        }        void IBoat.TurnLeft() {            Console.WriteLine("Turn boat left.");        }        void IBoat.TurnRight() {            Console.WriteLine("Turn boat right.");        }        public void FishFinder() {            Console.WriteLine("Fish finder in use.");        }        public void Rudder(){            Console.WriteLine("Adjust rudder."); }     } } 

Another reason to use explicit interface implementation is to hide some portion of a class or struct. The explicitly implemented members are hidden from clients of the class. You must cast the type to the interface to access the hidden interface members.

In the following code, the Car class inherits and implements the IVehicle and IEngine interface. The two interfaces have no overlapping members. A driver doesn't usually interface with the engine directly. That is usually left to the mechanic. Therefore, the IEngine interface is hidden in the Car class.

 using System; namespace Donis.CSharpBook{      public class Starter{         public static void Main(){             Car auto=new Car();              auto.IgnitionOn();              auto.IgnitionOff();              //  Access engine.              IEngine e=auto.AccessEngine();              //  Inspect engine.          }      }      public interface IVehicle {          void IgnitionOn();          void IgnitionOff();          void TurnLeft();          void TurnRight();      }      public interface IEngine {          void Alternator();          void Ignition();          void Transmission();      }      public class Car: IVehicle, IEngine{          public void IgnitionOn(){              Console.WriteLine("Ignition on.");              AccessEngine().Ignition();          }          public void IgnitionOff(){              Console.WriteLine("Ignition off.");          }          public void TurnLeft() {              Console.WriteLine("Turn left.");          }          public void TurnRight(){              Console.WriteLine("Turn right.");          }          public IEngine AccessEngine() {              return this;          }          void IEngine.Alternator(){              Console.WriteLine("Alternator.");          }          void IEngine.Ignition() {              Console.WriteLine("Ignition");          }          void IEngine.Transmission(){             Console.WriteLine("Transmission");         }    } } 

Reimplementation of Interfaces

A child class can reimplement an interface that was implemented in a base class. In the following code, ZClass inherits interface IZ. YClass inherits ZClass and reimplements the IZ interface. This interface reimplementation in the derived class hides the implementation of the base class. Unless the new modifier is specified, warnings will occur in the derived class.

     public interface IZ {         void MethodA();         void MethodB();     }     public class ZClass: IZ {         public void MethodA(){         }         public void MethodB(){         }     }     public class YClass: ZClass, IZ {         public new void MethodA(){         }         public new void MethodB(){         }     } } 




Programming Microsoft Visual C# 2005(c) The Language
Microsoft Visual Basic 2005 BASICS
ISBN: 0619267208
EAN: 2147483647
Year: 2007
Pages: 161

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