October 31, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Designing with Interfaces & Abstract Classes

  • November 8, 2006
  • By Matt Weisfeld
  • Send Email »
  • More Articles »

Interfaces

Before defining an interface, it is important to note that C++ does not have a construct called an interface. For C++, an abstract class provides the functionality of an interface. This raises an obvious question: If an abstract class can provide the same functionality as an interface, why do Java and C# bother to provide interfaces?

For one thing, C++ supports multiple inheritance whereas Java and C# do not. Although Java and C# classes can inherit from only one parent class, they can implement many interfaces. Using more than one abstract class constitutes multiple inheritance, thus Java and C# cannot go this route. Even though this explanation may specify the need for Java and C# interfaces, it does not really explain what an interface is. You need to explore what function an interface performs.

Note: Due to these considerations, interfaces are often thought to be a work-around for the lack of multiple inheritance. This is not technically true. Interfaces are a separate design technique, and although they can be used to design applications that could be done with multiple inheritance, they do not replace the concept of multiple inheritance.

As with abstract classes, interfaces are a powerful way to enforce contracts for a framework. Before you get into any conceptual definitions, it is helpful to see an actual interface UML diagram and the corresponding code. Consider an interface called Nameable, as shown in Figure 2.

Figure 2: A UML diagram of an interface.

Note that Nameable is identified in the UML diagram as an interface, which distinguishes it from a regular class (abstract or not). Also note that the interface contains two methods, getName () and setName (). Here is the corresponding code:

Listing 3

public interface Nameable {
   String getName();
   void setName (String aName);
}

In the code, notice that Nameable is not declared as a class, but as an interface. Because of this, both methods, getName () and setName (), are considered abstract and there is no implementation provided. An interface, unlike an abstract class, can provide NO implementation. As a result, any class that implements an interface must provide the implementation for all methods (in Java and C#, a class inherits from an abstract class whereas a class implements an interface).

Tying It All Together

If both abstract classes and interfaces provide abstract methods, what is the real difference between the two? As you saw before, an abstract class provides both abstract and concrete methods wheras an interface provides only abstract methods. Why is there such a difference?

Assume that you want to design a class that represents a dog, with the intent of adding more mammals later. The logical move would be to create an abstract class called Mammal:

Listing 4

public abstract class Mammal {
   public void generateHeat() {System.out.println("Generate heat");};
   public abstract void makeNoise();
}

This class has a concrete method called generateHeat () and an abstract method called makeNoise (). The method generateHeat () is concrete because all mammals generate heat. The method makeNoise () is abstract because each mammal will make noise differently.

Also, create a class called Head that you will use in a composition relationship:

Listing 5

public class Head {
   String size;
   public String getSize() {
      return size;
   }
   public void setSize(String aSize) {size = aSize;};
}

Head has two methods: getSize () and setSize (). Although composition might not shed much light on the difference between abstract classes and interfaces, using composition in this example does illustrate how composition relates to abstract classes and interfaces in the overall design of an object-oriented system. I feel that this is important because the example is more complete. Remember that there are two ways to build object relationships: the is-a relationship, represented by inheritance; and the has-a relationship, represented by composition. The question is: Where does the interface fit in?

To answer this question and tie everything together, create a class called Dog that is a subclass of Mammal, implements Nameable, and has a Head object (see Figure 3). The corresponding code is in Listing 6.

Figure 3: A UML diagram of the sample code.

In a nutshell, Java and C# build objects in three ways: inheritance, interfaces, and composition. Note the dashed line in Figure 3 that represents the interface. This example illustrates when you should use each of these constructs. When do you choose an abstract class? When do you choose an interface? When do you choose composition? Explore this idea further.

You should be familiar with the following concepts:

  • Dog is a Mammal, so the relationship is inheritance.
  • Dog implements Nameable, so the relationship is an interface.
  • Dog has a Head, so the relationship is composition.

Listing 6

public class Dog extends Mammal implements Nameable {
   String name;
   Head head;
   public void makeNoise(){System.out.println("Bark");};
   public void setName (String aName) {name = aName;};
   public String getName () {return (name);};
}

After looking at the UML diagram, you may come up with an obvious question: Even though the dashed line from Dog to Nameable represents an interface, isn't it still inheritance? At first glance, the answer is not simple. Although interfaces are a special type of inheritance, it is important to know what special means. Understanding these special differences is fundamental to a strong object-oriented design.

Although inheritance is a strict is-a relationship, an interface is not. For example:

  • A dog is a mammal.
  • A reptile is not a mammal.

Thus, a Reptile class could not inherit from the Mammal class. However, an interface transcends the various classes. For example:

  • A dog is nameable.
  • A lizard is nameable.

The key here is that classes in a strict inheritance relationship must be related. For example, in this design the Dog class is directly related to the Mammal class. A dog is a mammal. Dogs and lizards are not related at the mammal level because you can't say that a lizard is a mammal. However, interfaces can be used for classes that are not related. You can name a dog just as well as you can name a lizard. This is the key difference between using an abstract class and using an interface.

The abstract class represents some sort of implementation. In fact, you saw that Mammal provided a concrete method called generateHeat (). Even though you do not know what kind of mammal you have, you know that all mammals generate heat. However, an interface models only behavior. An interface never provides any type of implementation—only behavior. The interface specifies behavior that is the same across classes that conceivably have no connection. Not only are dogs nameable, but so are cars, planets, and so on.





Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel