An interface provides a specification rather than an implementation for its members.
Interfaces act as the contact between the definition and implementation.
Interface members are all implicitly abstract.
A class or struct can implement multiple interfaces.
An interface declaration is like a class declaration, but it provides no implementation for its members.
These members will be implemented by the classes and structs that implement the interface.
An interface can contain only methods, properties, events, and indexers.
Here is the definition of the IEnumerator
interface, defined in System.Collections
:
public interface IEnumerator { bool MoveNext(); object Current { get; } void Reset(); }
Interface members are always implicitly public
and cannot declare an access modifier.
Implementing an interface means providing a public implementation for all its members:
class Countdown : IEnumerator { int count = 11; public bool MoveNext () { return count-- > 0 ; } public object Current { get { return count; } } public void Reset() { throw new NotSupportedException(); } }
You can implicitly cast an object to any interface that it implements. For example:
IEnumerator e = new Countdown(); while (e.MoveNext()) Console.Write (e.Current);
Interfaces may derive from other interfaces.
For instance:
public interface IUndoable { void Undo(); } public interface IRedoable : IUndoable { void Redo(); }
IRedoable
"inherits" all the members of IUndoable
.
Implementing multiple interfaces can sometimes result in a collision between member methods.
We can resolve such collisions by explicitly implementing an interface member.
Consider the following example:
interface Interface1 { void iMethod(); } interface Interface2 { int iMethod(); } public class Widget : Interface1, Interface2 { public void iMethod () { Console.WriteLine ("Widget's implementation of Interface1.iMethod"); } int Interface2.iMethod(){ Console.WriteLine ("Widget's implementation of Interface2.iMethod"); return 42; } }
This lets the two methods coexist in one class. The only way to call an explicitly implemented member is to cast to its interface:
Widget w = new Widget();
w.iMethod(); // Widget's implementation of Interface1.iMethod
((Interface1)w).iMethod(); // Widget's implementation of Interface1.iMethod
((Interface2)w).iMethod(); // Widget's implementation of Interface2.iMethod
An implicitly implemented interface member is, by default, sealed.
It must be marked virtualor abstract in the base class in order to be overridden.
For example:
public interface IUndoable { void Undo(); } public class DrawPad : IUndoable { public virtual void Undo() { Console.WriteLine ("DrawPad.Undo"); } } public class RichDrawPad : DrawPad { public override void Undo() { Console.WriteLine ("RichDrawPad.Undo"); } }