Thursday, December 27, 2012

C++ : Interface classes

An interface class is a class that has no members variables, and where all of the functions are
pure virtual! In other words, the class is purely a definition, and has no actual implementation.
Interfaces are useful when you want to define the functionality that derived classes must
implement, but leave the details of how the derived class implements that functionality entirely
up to the derived class.

Interface classes are often named beginning with an I. Here’s a sample interface class:

class IErrorLog
{
    virtual bool OpenLog(const char *strFilename) = 0;
    virtual bool CloseLog() = 0;
    virtual bool WriteError(const char *strErrorMessage) = 0;
};
 
Any class inheriting from IErrorLog must provide implementations for all three functions in
order to be instantiated. You could derive a class named FileErrorLog, where OpenLog() opens a
file on disk, CloseLog() closes it, and WriteError() writes the message to the file. You could
derive another class called ScreenErrorLog, where OpenLog() and CloseLog() do nothing, and
WriteError() prints the message in a pop-up message box on the screen.
Now, let’s say you need to write some code that uses an error log. If you write your code so it
includes FileErrorLog or ScreenErrorLog directly, then you’re effectively stuck using that kind
of error log. For example, the following function effectively forces callers of MySqrt() to use a
FileErrorLog, which may or may not be what they want.
 
double MySqrt(double dValue, FileErrorLog &cLog)
{
    if (dValue < 0.0)
    {
        cLog.WriteError("Tried to take square root of value less than 0");
        return 0.0;
    }
    else
        return dValue;
}
 
A much better way to implement this function is to use IErrorLog instead:
 
double MySqrt(double dValue, IErrorLog &cLog)
{
    if (dValue < 0.0)
    {
        cLog.WriteError("Tried to take square root of value less than 0");
        return 0.0;
    }
    else
        return dValue;
}  
 
Now the caller can pass in any class that conforms to the IErrorLog interface. If they want the
error to go to a file, they can pass in an instance of FileErrorLog. If they want it to go to the
screen, they can pass in an instance of ScreenErrorLog. Or if they want to do something you
haven’t even thought of, such as sending an email to someone when there’s an error, they can
derive a new class from IErrorLog (eg. EmailErrorLog) and use an instance of that! By using
IErrorLog, your function becomes more independent and flexible.
Interface classes have become extremely popular because they are easy to use, easy to extend,
and easy to maintain. In fact, some modern languages, such as Java and C#, have added an
“interface” keyword that allows programmers to directly define an interface class without having
to explicitly mark all of the member functions as abstract. Furthermore, although Java and C#
will not let you use multiple inheritance on normal classes, they will let you multiply inherit as
many interfaces as you like. Because interfaces have no data and no function bodies, they avoid a
lot of the traditional problems with multiple inheritance while still providing much of the
flexibility. 
 
For Abstract Classes and Pure Virtual Functions, Check this link. 

No comments:

Post a Comment