Posted on March 5, 2008 07:18 by mcollins

If you interview with me for a job in our Phoenix office, you're most likely to get this question as your first question.  Why do I ask it?  Because I think that it's a good test of how well you understand the theory and practical applications of developing software using the modern languages such as C# and Java, and it also helps to understand how well you understand software design and the impacts behind the decisions that you make.  So for those interested parties, here's the answer...

There are three primary concepts to object-oriented development (or at least there were...I'm feeling old at 33 now):

Inheritance is the easiest of the three concepts to understand.  One type can inherit from another in order to get the features of the base type and expand them.  For example, a type may be Person.  Person may have three inheritors: Mother, Father, and Child.  All three inheritors are People (should be Persons, but I can't draw myself to use bad English this early in the morning), but each have different functions and do things differently.  For example, a Mother and a Father may do things with a specific purpose.  A child may do things without having a really good reason for doing things, such as throwing a ball at a window to see the effect said ball has on said window.

Encapsulation is basically the hiding of implementation details "behind the curtain."  An object's state and data isn't important to a caller.  It's the operations and the benefit that one object gives to another that's important.  The implementation details are "encapsulated" inside the object providing a service.

To me, polymorphism is the ability of one type to use many combinations of other types.  For example, under this definition, polymorphism could be Microsoft Office Word working with many different add-ins.  Polymorphism could be exhibited by the device drivers used by an operating system.  The operating system defines the interfaces that device drivers must adhere to, and the device drivers implement the interface according to the specification.  In the case of Word, add-ins implement a standard interface, but could themselves either be their own applications or may interface with yet another application to perform their business logic.  In the later case, an add-in is basically transforming another application into an add-in for Microsoft Office Word.

At it's most basic level, an interface is a contract and a specification for a software component.  Using interfaces, one can achieve polymorphism.  An abstract class is the basic definition of a type of objects, with basic definitions of common or shared behaviors, that can be inherited from and expanded upon.

Let's see an example.  At any company, there could be many employees.  We might start by defining the following class:

   1: public abstract class Employee {
   2:     public abstract void ShutUpAndDoWork();
   3:     public virtual void RecordTimeWorked();
   4: }

Our Employee class is declared as an abstract class with two methods.  The first method, ShutUpAndDoWork, is declared as being abstract because while this is an employee, we haven't classified what kind of employee this is yet, so we don't know what kind of work the employee will perform.  The employee could be an accountant, in which case we'll have to define an Accountant subclass of Employee and implement logic for balancing the general journal and general ledger.  The employee could be a trainer, in which case we'll have to implement classroom management and public speaking skills for the employee.  The second method, RecordTimeWorked, is an activity that all employees must do, and must typically do in the same way, with some minor differences.  Some employees may use our basic implementation of RecordTimeWorked.  Some employees may need to fill our their time card and then have their manager sign it, in which case we can still use the basic implementation but then have to extend it to get the manager's signature.

Now, we're going to define a new type for a manager:

   1: public class Manager : Employee {
   2:     public override void ShutUpAndDoWork();
   3:     public virtual void AuthorizeTimeCards();
   4: }

Here, we've defined the Manager class and extended the Employee class.  The Manager is also an employee of the company with his own responsibilities to perform.  We've also added an extra responsibility for authorizing time cards for the employees that work for the manager.  In this example, the Manager's responsibilities for recording time worked is the same as the basic Employee's, so we've inherited the functionality and behavior provided to us by the abstract base class.  Inheritance at it's finest!

Let's say, as we get up to higher levels of managers, it becomes harder to get the manager's time.  An executive, for example, may be traveling quite often around the world if you work for an international organization.  It wouldn't be realistic for the executive to make employees wait to get their time cards signed.  Often there are laws in place that employees must be paid regularly.  In this case, the executive may have a personal assistant that always stays local and can act as a proxy for him when he's away traveling or on vacation.  This leads us to a predicament.  How can employees get their time cards signed by this assistant?  The assistant isn't necessarily a manager, so he can't be represented by the Manager class.  This leads us to interfaces and polymorphism.  Imagine the following interface:

   1: public interface IManager {
   2:     void AuthorizeTimeCards();
   3: }

The IManager interface defines the AuthorizeTimeCards operation that all managers must implement.  We'll then redefine our Manager class to look like this:

   1: public class Manager : Employee, IManager {
   2:     public override void ShutUpAndDoWork();
   3:     public virtual void AuthorizeTimeCards();
   4: }

Our Manager class now implements the IManager interface and implements the AuthorizeTimeCards operation required by the interface.  We can also go one step further and declare our Assistant class:

   1: public class Assistant : Employee, IManager {
   2:     public override void ShutUpAndDoWork();
   3:     public virtual void AuthorizeTimeCards();
   4: }

Our Assistant class defines Assistants as Employees, but they also implement the IManager interface although they're not managers.  However, by implementing this interface, the Assistant can act as a proxy for a manager or executive if the manager or executive is not available.  In this case, Employees can call upon the IManager interface of the Assistant class to complete their duties with respect to their Managers if their Managers are not available.  Polymorphism at it's finest!  Employees don't necessarily care that the person approving their time cards for them is not their manager.  The main thing is that the Assistant implements the IManager interface, which the Employees use, and the Assistant has the ability to authorize the Employee time cards.

This is the difference between an interface and an abstract class.  Extra points during your interview if you use my example.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5