One way tocreate reusable code is to create frameworks. In this chapter, we focus onusing interfaces and abstract classes to create frameworks and encouragereusable code.
Hand-in-handwith the concept of code reuse is the concept of standardization, which is sometimes called plug-and-play(即插即用).
The person orpersons who wrote the class, classes, or class libraries should have provideddocumentation on how to use the public interfaces of the class, classes, orclass libraries (at least we hope). In many cases, this takes the form of the application-programminginterface (API).
Dictionary.com(http://www.dictionary.com) defines a contract asan agreement between two or more parties for the doing or not doing ofsomething specified—an agreement enforceable by law.”
In Java and the.NET languages, the two ways to implement contracts are to use abstract classesand interfaces.
public abstract class Shape {
publicabstract void draw(); // no implementation
}
Note that theclass does not provide any implementation for draw(); basically there is no code and this is what makesthe method abstract (providing any code would make the method concrete).
public class Circle extends Shape {
public voidDraw() {System.out.println (“Draw a Circle”};
}
public class Rectangle extends Shape {
public voidDraw() {System.out.println (“Draw a Rectangle”};
}
Circle
If Circle does indeed fail toimplement a draw() method, Circle will be considered abstract
itself.
Before definingan interface, it is interesting to note that C++ does not have a constructcalled an interface. For C++, an abstract class provides the functionality ofan interface.
Figure 8.4 A UML diagram of a Java interface.
public interface Nameable {
StringgetName();
void setName(String aName);
}
Implementation Versus Definition Inheritance
Sometimes inheritance is referred to as implementationinheritance,and interfaces are called definition inheritance.
As we sawbefore, an abstract class provides both abstract and concrete methods, whereasan interface provides only abstract methods.
Figure 8.5 A UML diagram of the sample code.
In a nutshell
英[in ə ˈnʌtˌʃel]美[ɪn e ˈnʌtˌʃɛl]
简言之;一言以蔽之;简单地;简约地
Note the dashed line(短划线) in Figure 8.5 that represents the interface.
You should befamiliar with the following concepts:
n Dog is aMammal, so the relationship is inheritance.
n Dog implements Nameable, so the relationship is an interface.
n Dog has a Head, so the relationship is composition.
public class Dog extends Mammal implementsNameable {
String name;
Head head;
public voidmakeNoise(){System.out.println(“Bark”);}
public voidsetName (String aName) {name = aName;}
public StringgetName () {return (name);}
}
A Reptile class could not inherit from the Mammal class. However, an interface transcends the variousclasses.
An interface never provides any type of implementation, only behavior.
抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。
we can performthe true test of the interface. Is an interface an actual is-a relationship? Thecompiler thinks so:
Dog D = new Dog();
Nameable N = D;
This code worksfine. So, we can safely say that a dog is a nameable entity. This is a simple buteffective proof that both inheritance and interfaces constitute an is-arelationship.
The Planet class, the Car class, and the Dog class would all have the same naming syntax.
To implementthis lofty goal,we can create an interface (we can use the Nameable interface that we used previously).The conventionis that all classes must implement Nameable.
Basically, contracts are“plug-in points” into your code.
Instead ofcoupling to objects of specific classes, you can connect to any object thatimplements the contract.
They might makecode reuse more of a reality, but they make things somewhat more complex.
In this section,we’ll walk through a simple but practical example of how to create a workableframework using inheritance, abstract classes, interfaces and composition.
Now, how can weleverage the code that we used for the pizza shop in the system for the donutshop?
Figure8.6 Applicationson divergent paths.
In this example,the applications testDonutShop and testPizzaShop are totally independent code modules.
For example, oneday Papa’s website crashes. The developer fixes the problem.
Because thedeveloper does not yet totally understand the problem and because Dad’s systemis working fine, the code is not migrated to the donut shop’s system.
Tracking Down a Bug
The fact that the bug turned up in the pizza system doesnot mean that it will also turn up in
the donut system. Even though the bug caused a crash inthe pizza shop, the donut shop
might never encounter it. It may be that the fix to the pizzashop’s code is more dangerous
to the donut shop than the original bug.
Version2.01papa
Version 2.03dad
This becomes a mess. Our goal is to avoid the mess of the previousexample.
What we want todo is factor out as much commonality as possible.
In this case,wewill create an abstract class to factor out some of the implementation, and aninterface (our familiar Nameable) tofactor out some behavior.
Our goal is toprovide customized versions of our Web application, with the followingfeatures:
n Aninterface, called Nameable, which is part of thecontract.
n Anabstract class called Shop,which is also part of the contract.
n Aclass called CustList, which we use in composition.
n Anew implementation of Shop foreach customer we service.
Figure8.7 AUML diagram of the Shop system.
If we add a GroceryShop application,we only have to provide theimplementation and the appropriate string to the main application.
This chapterdiscusses the primary topics of building objects: inheritance, interfaces, andcomposition. In this chapter, you have learned how to build reusable code bydesigning with contracts.