Interface Implementation


Before moving on, it's worth taking a closer look at how you go about defining and implementing interfaces. In the last chapter, you saw that interfaces are defined in a similar way to classes, using code such as:

interface IMyInterface {    // Interface members. }

Interface members are defined like class members except for a few important differences:

  • No access modifiers (public, private, protected, or internal) are allowed — all interface members are implicitly public.

  • Interface members can't contain code bodies.

  • Interfaces can't define field members.

  • Interface members can't be defined using the keywords static, virtual, abstract, or sealed.

  • Type definition members are forbidden.

You can, however, define members using the new keyword if you wish to hide members inherited from base interfaces. For example:

 interface IMyBaseInterface { void DoSomething(); } interface IMyDerivedInterface : IMyBaseInterface { new void DoSomething(); } 

This works in exactly the same way as hiding inherited class members.

Properties defined in interfaces define either or both of the access blocks, get and set, which are permitted for the property. For example:

interface IMyInterface { int MyInt { get; set; } }

Here, the int property MyInt has both get and set accessors. Either of these may be omitted for a property with more restricted access.

Note, though, that interfaces do not specify how the property should be stored. Interfaces cannot specify fields, for example, which might be used to store property data.

Finally, interfaces, like classes, may be defined as members of classes (but not as members of other interfaces, since interfaces cannot contain type definitions).

Implementing Interfaces in Classes

A class that implements an interface must contain implementations for all members of that interface, which must match the signatures specified (including matching the specified get and set blocks), and must be public. For example:

 public interface IMyInterface { void DoSomething(); void DoSomethingElse(); } public class MyClass : IMyInterface { public void DoSomething() { } public void DoSomethingElse() { } } 

It is also possible to implement interface members using the keywords virtual or abstract, but not static or const. Interface members may also be implemented on base classes, for example:

public interface IMyInterface {    void DoSomething();    void DoSomethingElse(); } public class MyBaseClass { public void DoSomething() { } } public class MyDerivedClass : MyBaseClass, IMyInterface { public void DoSomethingElse() { } } 

Inheriting from a base class that implements a given interface means that the interface is implicitly supported by the derived class, for example:

 public interface IMyInterface { void DoSomething(); void DoSomethingElse(); } public class MyBaseClass : IMyInterface { public virtual void DoSomething() { } public virtual void DoSomethingElse() { } } public class MyDerivedClass : MyBaseClass { public override void DoSomething() { } } 

As shown in the preceding example, it is useful to define implementations in base classes as virtual, so that derived classes can replace the implementation rather than hiding it. If you were to hide a base class member using the new keyword rather than overriding it in this way, then the method IMyInterface.DoSomething() would always refer to the base class version, even if the derived class were being accessed via this interface.

Explicit Interface Member Implementation

Interface members can also be implemented explicitly by a class. If you do this, then the member can only be accessed through the interface, not through the class. Implicit members, which are what you used in the code in the last section, can be accessed either way.

For example, if the class MyClass implemented the DoSomething() method of IMyInterface implicitly, as in the preceding example, then the following code would be valid:

 MyClass myObj = new MyClass(); myObj.DoSomething(); 

as would be:

 MyClass myObj = new MyClass(); IMyInterface myInt = myObj; myInt.DoSomething(); 

Alternatively, if MyDerivedClass implements DoSomething() explicitly, then only the latter technique is permitted. The code for doing this is:

 public class MyClass : IMyInterface { void IMyInterface.DoSomething() { } public void DoSomethingElse() { } } 

Here DoSomething() is implemented explicitly and DoSomethingElse() implicitly. Only the latter is accessible directly through an object instance of MyClass.

Adding Property Accessors with Nonpublic Accessibility

I said earlier that if you implement an interface with a property, then you must implement matching get/set accessors. This isn't strictly true — it is possible to add a get block to a property in class where the interface defining that property only contains a set block, and vice versa. However, this is only possible if you add the accessor with an accessibility modifier that is more restrictive than the accessibility modifier on the accessor defined in the interface. Since the accessor defined by the interface is, by definition, public, this means that you can only add nonpublic accessors. For example:

 public interface IMyInterface { int MyIntProperty { get; } } public class MyBaseClass : IMyInterface { protected int myInt; public int MyIntProperty { get { return myInt; } protected set { myInt = value; } } } 




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