Component-Based Software Engineering Using Interfaces Paul Krause
Lecture 4 - Using Interfaces Contents Introduction Interfaces vs. Abstract Classes A Digression on “Casting” making lawyers human making lawyers human Back to the Phone Directory
Introduction We will use a Telephone Directory as a case study to illustrate the use of components and interfaces This is taken from: Objects, Abstraction, Data Structures and Design Using Java Version 5.0 Authors: Elliot Koffman and Paul Wolfgang Publisher : John Wiley
Interfaces Sometimes we may find two or more different subclasses share some common behaviour In this case, they are not strictly “kinds of” some common parent Rather, they “behave like” some common pattern (under certain circumstances) We say that they both implement a common interface
A “Cashier” Interface PersonMachine ATMEmployee «interface» Cashier withdraw deposit
Java interfaces public interface Cashier { public void deposit(int id, double amount); public boolean withdraw(int id, double amount); } Note: An interface is pure specification - it contains no implementation An interface is pure specification - it contains no implementation
Lecture 4 - Using Interfaces Contents Introduction Interfaces vs. Abstract Classes A Digression on “Casting” making lawyers human making lawyers human Back to the Phone Directory
cf Abstract Classes
Abstract Class vs. Interface public abstract class EllipticalShape { public abstract double area( ); public abstract double circumference( ); } public interface Cashier { public void deposit(int id, double amount); public boolean withdraw(int id, double amount); }
What are the differences? Abstract Class Can include class and instance fields May include concrete implementations of methods A concrete class can only extend a single abstract class Interface Can only include static final fields All methods must be abstract declarations - no implementation A class can implement multiple interfaces
Why use interfaces? Design Guideline: “When the functionality supported by a class can be implemented in different ways, it is advisable to separate the interface from the implementation” Xiaoping Jia Object-Oriented Software Development Using Java
Chili PizzaExpress EventObject source getSource() toString() Bakery addOrderListener() removeOrderListener() sendMessage(PizzaEvent) fires passed to registers with 0..* invokes notifications in0..* «interface» OrderListener pizzaStatus(evt) Customer run( ) iNumber iSliceNumber PizzaEvent
Class Bakery private void sendMessage(PizzaEvent anEvent) { Vector v; synchronised(this) { v = (Vector) iCustomers.clone( ); v = (Vector) iCustomers.clone( ); } for (int i=0; i<v.size( ); i++) { OrderListener ol = (OrderListener)v.elementAt(i); OrderListener ol = (OrderListener)v.elementAt(i); ol.pizzaStatus(anEvent); ol.pizzaStatus(anEvent); }}}
General Idiom To send an event to a Customer, the Bakery needs to know: the name of the method to invoke in a Customer the name of the method to invoke in a Customer the type of the Event to send when invoking the respective method the type of the Event to send when invoking the respective method this information is contained in the OrderListener interface that is all the Bakery needs to know that is all the Bakery needs to know
Lecture 4 - Using Interfaces Contents Introduction Interfaces vs. Abstract Classes A Digression on “Casting” making lawyers human making lawyers human Back to the Phone Directory
A Diversion on “Casting” In the last example, we were only interested in the “OrderListener” behaviour of Customers: OrderListener ol = (OrderListener)v.elementAt(i); We “cast” an element of the Vector v This is a way of converting one type to another, subject to certain rules
Casting between Data Types Suppose I wish to add a double precision value to an integer, and just keep the integer value of the answer: double x = 24.2; int y = 1; int z = (int) (x - y); We have explicitly cast (“converted”) the result of the calculation into an integer
Rules for Data Types An explicit cast is needed when converting from a “larger” (more information) type to a “smaller” one (e.g. double to int) This is not needed when casting to a larger type - the compiler will do it for you
Rules for Casting Objects An instance of a class may only be cast into subclasses or superclasses in its inheritance hierarchy Human h; Lawyer l; l = new Lawyer( ); h = (Human) l; You can use an instance of a class, anywhere an instance of one of its superclasses is expected
W.r.t. Interfaces You can cast an object to an interface type if (and only if) the class of that object implements the interface This will give full access to the services provided by the interface,e.g.: OrderListener ol = (OrderListener)v.elementAt(i);
Lecture 4 - Using Interfaces Contents Introduction Interfaces vs. Abstract Classes A Digression on “Casting” making lawyers human making lawyers human Back to the Phone Directory
Class Diagram (from Koffman and Wolfgang)
Directory Entry Class
PhoneDirectory Interface
(At least) Two implementations of PDUserInterface > PDUserInterface processCommands( ) PDConsoleUI processCommands( ) PDGUI processCommands( )
An Implementation of the PhoneDirectory Interface (I)
An Implementation of the PhoneDirectory Interface (II)
Java Implementation ArrayBasedPD + loadData( ) + addOrChangeEntry( ) +lookupEntry( ) + removeEntry( ) + save( ) DirectoryEntry + DirectoryEntry(String name, String number ) + String getName( ) + String getNumber( ) + void setNumber(String number) - String name - String number collects together is stored in 0.. * 1
Exercise: Implement this! DirectoryEntry + DirectoryEntry(String name, String number ) + String getName( ) + String getNumber( ) + void setNumber(String number) - String name - String number
Phone Directory Interface public interface PhoneDirectory { /** Load the data file containing the directory, or /** Load the data file containing the directory, or * establish a connection with the data source. * establish a connection with the data source. sourceName The name of the file (data source) sourceName The name of the file (data source) * with the phone directory entries * with the phone directory entries */ */ void loadData(String sourceName); void loadData(String sourceName); /** Look up an entry /** Look up an entry name The name of the person to be looked up name The name of the person to be looked up The number, or null if the name is not in the directory The number, or null if the name is not in the directory */ */ String lookupEntry(String name); String lookupEntry(String name);…