An
interface is functionally similar to an
abstract class.
You don't instantiate
interfaces, they don't contain constants, fields, operators,
constructors, destructors, or types. They only contain one or more method signatures, without any method
definitions. Sounds a bit strange, doesn't it?
One of the most common tools in computer programming is sorting a collection of data, based on one or more
sorting criteria. This can be simple enough for collections of primitive data types (e.g. integers, characters),
but can still be applied to collections of objects from a class, as long as there's some programmer-defined
way by which objects from this classes are to be sorted. For example, I might sort the collection of
Student objects enrolled into my
Course, based on the
number of points they've accumulated from quizzes, assignments, and exams. One approach to this would be
to define a predicate function that defines the sorting criteria for objects from your class, passing it as
an argument to a
sort function available from a standard library. Something like:
bool myCompare(const Slacker& left, const Slacker& right)
{
return (left.totalPoints < right.totalPoints);
}
...
sort(mySlackerArray, myCompare);
// Where the first argument is my collection to be sorted,
// and the second is the manner by which they will be sorted
Instead, an
interface defines this predicate method within itself, with classes
and structs implementing it as part of their definition. This will then allow objects instantiated from
these classes to conform to commonly used methods in our programs, such as
Array.Sort(Object[] array). As long as you implement the
interface
called
IComparable, which contains a single method prototype:
int CompareTo(Object alpha);
Where the return value will be < 0 if
this < alpha; == 0 if
this == alpha; and > 0 if
this > alpha. One important
thing to note is that our primitive data types already have this interface implemented. So let's see an example
of this:
public class Student : IComparable // Student is intended to implement this interface
{
string ZID;
uint32 totalPoints;
// Constructors, methods, other fancy jazz
public int CompareTo(Object alpha)
{
if (alpha == null) throw new ArgumentNullException(); // Always... check for null values
Student rightOp = alpha as Student; // Oo, typecasting using English! I like it
if (rightOp != null) // Protect against a failed typecasting
return totalPoints.CompareTo(rightOp.totalPoints); // Making use of what's already available!
else
throw new ArgumentException("[Student]:CompareTo argument is not a Student");
}
}
This will then allow me to predictably use
Array.Sort(enrolledStudents).
Another useful
Interface to have implemented is
IEnumerable,
which can usually be used to allow for a
foreach loop to be used on an
object from your class, which contains a collection of values as an attribute. For example: expanding
on the
Student class above, if we were to create a
Course
class as well, which contained an array or other Collection of ID's for each of the
Student
objects enrolled into this class, we could use this code:
foreach (uint i in thisCourse)
// do stuff
In order to iterate over each of those ID's. The details for implementing this are non-trivial compared
to the
IComparable's single method, but are also just cut 'n paste from an
existing, working implementation. Such as found from the MSDN documentation on the
IEnumerable Interface found
here. You'll obviously want to update the names of things from their Person example.
While classes may only inherit from a single source,
Interfaces may be
implemented by an unlimited number of classes, and any given class or struct may implement as many
interfaces as you would like. Some common
interfaces
to consider regularly implementing for the classes you develop include:
IComparable { int CompareTo(Object); }
IEquatable<T> { bool Equals(T); } // Where T is a specific data type
IDisposable { void Dispose(); } // Defines garbage collection, necessary when "using"
INotifyPropertyChange { event PropertyChangedEventHandler PropertyChanged; } // Not a method!
You might notice all these
interfaces begin with an I. That is the naming
convention you're encouraged to use going forward.
More on interfaces from Professor Hutchins' CSCI 473 course website.