November 27, 2014
Hot Topics:

Designing with Interfaces & Abstract Classes

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

The Compiler Proof

Can you prove or disprove that interfaces have a true is-a relationship? In the case of Java, you can let the compiler tell you. Consider the following code:

Dog D = new Dog();
Head H = D;

When this code is run through the compiler, the following error is produced:

Test.java:6: Incompatible type for Identifier.
Can't convert Dog to Head. Head H = D;

Obviously, a dog is not a head. However, as expected, the following code works just fine:

Dog D = new Dog();
Mammal M = D;

This is a true inheritance relationship, and it is not surprising that the compiler parses this code cleanly because a dog is a mammal.

Now, you can perform the true test of the interface. Is an interface an actual is-a relationship? The compiler thinks so:

Dog D = new Dog();
Nameable N = D;

This code works fine. So, you can safely say that a dog is a nameable entity. This is a simple but effective proof that both inheritance and interfaces constitute an is-a relationship.

Making a Contract

The simple rule for defining a contract is to provide an unimplemented method, via either an abstract class or an interface. Thus, when a subclass is designed with the intent of implementing the contract, it must provide the implementation for the unimplemented methods in the parent class or interface.

As stated earlier, one of the advantages of a contract is to standardize coding conventions. You can explore this concept in more detail by providing a good example of what happens when coding standards are not used. In this case, there are three classes: Planet, Car, and Dog. Each class implements code to name the entity. However, because they are all implemented separately, each class has different syntax to retrieve the name. Consider the following code for the Planet class:

Listing 7

public class Planet {
   String planetName;
   public void getplanetName() {return planetName;};
}

Likewise, the Car class may have code like this:

Listing 8

public class Car {
   String carName;
   public String getCarName() { return carName;};
}

And the Dog class may have code like this:

Listing 9

public class Dog {
   String dogName;
   public String getDogName() { return dogName;};
}

The obvious problem here is that anyone using these classes would have to look at the documentation (what a horrible thought) to figure out how to retrieve the name in each of these cases. Even though looking at the documentation is not the worst fate in the world, it would be nice if all the classes used in a project (or company) would use the same naming convention. It would make life a bit easier. This is where the Nameable interface comes in.

The idea would be to make a contract for any type of class that needs to use a name. As users of various classes move from one class to the other, they would not have to figure out the current syntax for naming an object. The Planet class, the Car class, and the Dog class would all have the same naming syntax.

To implement this lofty goal, you can create an interface (you can use the Nameable interface that you created previously). The convention is that all classes must implement Nameable. In this way, the users only have to remember a single interface for all classes when it comes to naming conventions:

Listing 10

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

The new classes—Planet, Car, and Dog—should look like this:

Listing 11

public class Planet implements Nameable {
   String planetName;
   public String getName() {return planetName;};
   public void setName(String myName) {planetName = myName;};
}
public class Car implements Nameable {
   String carName;
   public String getName() {return carName;};
   public void setName(String myName) {carName = myName;};
}
public class Dog implements Nameable {
   String dogName;
   public String getName() {return dogName;};
   public void setName(String myName) {dogName = myName;};
}

In this way, you have a standard interface and you have used a contract to ensure that it is the case.

There is one little issue that you may have thought about. The idea of a contract is great as long as everyone plays by the rules, but what if some shady individual does not want to play by the rules (the rogue programmer)? The bottom line is that there is nothing to stop someone from breaking the standard contract; however, in some cases doing so will get them in deep trouble.

On one level, a project manager can insist that everyone use the contract just like team members must use the same variable naming conventions and configuration management system. If a team member fails to abide by the rules, he or she could be reprimanded or even removed from the team.

Enforcing rules is one way to ensure that contracts are followed, but there are instances in which breaking a contract will result in unusable code. Consider the Java interface Runnable. Java applets implement the Runnable interface because it requires that any class implementing Runnable must implement a run () method. This is important because the browser that calls the applet will call the run () method within Runnable. If the run () method does not exist, things will break.

Conclusion

Basically, contracts are "plug-in points" into your code. Any place where you want to make parts of a system abstract, you can use a contract. Instead of coupling to objects of specific classes, you can connect to any object that satisfies the contract. Abstract classes and interfaces provide the mechanism to implement these design techniques. By utilizing these object-oriented concepts, you can produce solid designs that are reliable, flexible, reusable, and very maintainable.

References

  • www.sun.com
  • Just Java 2, 6th Edition. Peter van der Linden. 2004, Sun Microsystems.

About the Author

Matt Weisfeld is a faculty member at Cuyahoga Community College (Tri-C) in Cleveland, Ohio. Matt is a member of the Information Technology department, teaching programming languages such as C++, Java, C#, and .NET as well as various Web technologies. Prior to joining Tri-C, Matt spent 20 years in the information technology industry gaining experience in software development, project management, business development, corporate training, and part-time teaching. Matt holds an MS in computer science and an MBA in project management. Besides The Object-Oriented Thought Process, which is now in its second edition, Matt has published two other computer books, and more than a dozen articles in magazines and journals such as Dr. Dobb's Journal, The C/C++ Users Journal, Software Development Magazine, Java Report, and the international journal Project Management. Matt has presented at conferences throughout the United States and Canada.





Page 3 of 3



Comment and Contribute

 


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

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel