רישום תוכנית
רישום מלא של התוכנית מוצג להלן כך שתוכל לסקור את חלקי הקוד בהקשר.
/*File Callback04.java Copyright 1997, R.G.Baldwin The purpose of this program is to develop a callback capability using Interfaces. This is an enhanced version of the program named Callback03. You should familiarize yourself with the earlier program before getting into this program. This version of the program makes two unrelated enhancements to the program named Callback03. First, a new class is defined in conjunction with the CallBack interface that makes it possible for the Teacher class to encapsulate information into an object and pass that object whenever a callback is made. Second, a new class is defined in conjunction with the CallBack interface which, in Java terminology, is often called an adapter class. This is a convenience class that implements the interface and defines all the methods declared in the interface with empty methods. Then any class that needs to implement the interface can extend the adapter class without a requirement to define those methods that are not of interest. In this case, the interface is expanded to declare several dummy methods to emphasize this benefit of the use of an adapter class. Note that objects of classes that extend the adapter class that implements the interface can be referred to by the interface type. Thus, interface type is an inherited attribute that results from extending a class. Using an adapter class also makes it possible to expand the interface later by declaring new methods without breaking code that already implements the interface. This version defines three different classes named Student, Dog, and Cat, that implement the CallBack interface indirectly by extending the adapter class. These classes simply don't bother to define methods of the interface that are not of interest. Mixed objects of these three types are maintained on a list and notified at CallBack time. The Dog class ignores the recess() callback and the Cat class ignores the lunch() callback. The Student class responds to both types of callbacks with fully- defined methods. The program defines a Teacher class that has the ability to create and maintain a list of objects of the interface type, and to notify those objects that something interesting has happened by invoking either the recess() method or the lunch() method on all the objects on the list. Finally, the program defines a controlling class that ties all the pieces together and exercises them. Tested using JDK 1.1.3 under Win95. The output from the program was: Tom Recess Sue Recess CleoCat Recess Peg Recess KittyKat Recess Bob Recess Tom Lunch SpotDog Lunch Sue Lunch FidoDog Lunch Peg Lunch Bob Lunch BrownieDog Lunch **********************************************************/ import java.util.*; //First we define an interface that will create a new type // and declare two generic methods that can be used to // callback any object that is of a class that implements // the interface. Note that the methods now require a // parameter. Note also that we have declared several // additional dummy methods to emphasize the benefit of // extending the adapter class that is defined later. interface CallBack{ public void recess(CallBackObjectClass obj); public void lunch(CallBackObjectClass obj); public void dummy1(CallBackObjectClass obj); public void dummy2(CallBackObjectClass obj); public void dummy3(CallBackObjectClass obj); public void dummy4(CallBackObjectClass obj); public void dummy5(CallBackObjectClass obj); public void dummy6(CallBackObjectClass obj); }//end interface CallBack //=======================================================// //Now we need a class that can be instantiated to // pass an object in the callback methods. class CallBackObjectClass{ String data; CallBackObjectClass(String data){//constructor this.data = data; }//end constructor }//end CallBackObjectClass //=======================================================// //Now we need an adapter class for the CallBack interface. // This class defines all the interface methods with // empty methods. Classes that need the interface can // now extend this class and override only the empty // methods of interest, and ignore the others. Note that // objects of a class that extends this class can be // referenced as the interface type CallBack. class CallBackAdapter implements CallBack{ public void recess(CallBackObjectClass obj){}; public void lunch(CallBackObjectClass obj){}; public void dummy1(CallBackObjectClass obj){}; public void dummy2(CallBackObjectClass obj){}; public void dummy3(CallBackObjectClass obj){}; public void dummy4(CallBackObjectClass obj){}; public void dummy5(CallBackObjectClass obj){}; public void dummy6(CallBackObjectClass obj){}; }//end class CallBackAdapter //=======================================================// //Next we need a class whose objects can maintain a // registered list of objects of type CallBack and can // notify all the objects on that list when something // interesting happens. This class has the ability to // notify two different types of callbacks, recess() // and lunch(). class Teacher{ Vector objList; //list of objects of type CallBack //-----------------------------------------------------// Teacher(){//constructor //Instantiate a Vector object to contain the list // of registered objects. objList = new Vector(); }//end constructor //-----------------------------------------------------// //Method to add objects to the list. synchronized void register(CallBack obj){ this.objList.addElement(obj); }//end register() //-----------------------------------------------------// //Method to remove objects from the list. synchronized void unRegister(CallBack obj){ if(this.objList.removeElement(obj)) System.out.println(obj + " removed"); else System.out.println(obj + " not in the list"); }//end register() //-----------------------------------------------------// //Method to notify all objects on the list that // something interesting has happened regarding // recess and to pass information to the object // encapsulated in an object as a parameter. void callRecess(){ Vector tempList;//save a temporary copy of list here //Make a copy of the list. synchronized(this){ tempList = (Vector)objList.clone(); }//end synchronized block //Invoke the recess() method on each object on // the list, passing an object as a parameter. for(int cnt = 0; cnt < tempList.size(); cnt++){ ((CallBack)tempList.elementAt(cnt)).recess( new CallBackObjectClass(" Recess")); }//end for loop }//end callRecess() //-----------------------------------------------------// //Method to notify all objects on the list that // something interesting has happened regarding // lunch and to pass an object containing information // as a parameter to the callback method. void callLunch(){ Vector tempList;//save a temporary copy of list here //Make a copy of the list. synchronized(this){ tempList = (Vector)objList.clone(); }//end synchronized block //Invoke the lunch() method on each object on // the list, passing an object as a parameter. for(int cnt = 0; cnt < tempList.size(); cnt++){ ((CallBack)tempList.elementAt(cnt)).lunch( new CallBackObjectClass(" Lunch")); }//end for loop }//end callRecess() //-----------------------------------------------------// }//end class Teacher //=======================================================// //Class that implements the CallBack interface indirectly // by extending the CallBackAdapter class. Objects // of this class can be registered on the list maintained // by an object of the Teacher class, and will be notified // whenever that object invokes either the recess() method // or the lunch() method on the registered objects on // the list. This method provides a full definition for // both methods. class Student extends CallBackAdapter{ String name; //store the object name here for later ID //-----------------------------------------------------// Student(String name){//constructor this.name = name; //save the name to identify the obj }//end constructor //-----------------------------------------------------// //An object of the Teacher class can invoke this method // as a callback mechanism. Note that this method // displays the data encapsulated in the incoming // object. public void recess(CallBackObjectClass obj){//announce System.out.println(name + obj.data); }//end overridden recess() //-----------------------------------------------------// //An object of the Teacher class can also invoke this // method as a callback mechanism passing an object // as a parameter. public void lunch(CallBackObjectClass obj){//announce System.out.println(name + obj.data); }//end overridden lunch() //-----------------------------------------------------// }//end class Student //=======================================================// //Another Class that implements the CallBack interface // indirectly by extending the CallBackAdapter class. // See description above. This class ignores the recess() // method as well as the dummy methods. class Dog extends CallBackAdapter{ String name; //store name here for later ID //-----------------------------------------------------// Dog(String name){//constructor this.name = name; //save the name to identify the obj }//end constructor //-----------------------------------------------------// //An object of the Teacher class can invoke this // method as a callback mechanism passing an object // as a parameter. public void lunch(CallBackObjectClass obj){//announce System.out.println(name + obj.data); }//end overridden lunch() //-----------------------------------------------------// }//end class Dog //=======================================================// //A third Class that implements the CallBack interface // indirectly by extending the CallBackAdapter class, // similar to the other two classes. This class ignores // the lunch() method as well as the dummy methods. class Cat extends CallBackAdapter{ String name; //store name here for later ID //-----------------------------------------------------// Cat(String name){//constructor this.name = name; //save the name to identify the obj }//end constructor //-----------------------------------------------------// //An object of the Teacher class can invoke this method // as the callback mechanism, passing an object as a // parameter. public void recess(CallBackObjectClass obj){//announce System.out.println(name + obj.data); }//end overridden recess() //-----------------------------------------------------// }//end class Cat //=======================================================// //Controlling class that ties all the pieces together and // exercises them. class Callback04{ public static void main(String[] args){ //Instantiate Teacher object Teacher missJones = new Teacher(); //Instantiate some Student objects Student tom = new Student("Tom"); Student sue = new Student("Sue"); Student peg = new Student("Peg"); Student bob = new Student("Bob"); Student joe = new Student("Joe"); //Instantiate some Dog objects. Dog spot = new Dog("SpotDog"); Dog fido = new Dog("FidoDog"); Dog brownie = new Dog("BrownieDog"); //Instantiate some Cat objects Cat cleo = new Cat("CleoCat"); Cat kitty = new Cat("KittyKat"); //Register some Student, Dog, and Cat objects with // the Teacher object. missJones.register(tom); missJones.register(spot); missJones.register(sue); missJones.register(cleo); missJones.register(fido); missJones.register(peg); missJones.register(kitty); missJones.register(bob); missJones.register(brownie); //Cause the Teacher object to call recess on all // the objects on the list. missJones.callRecess(); //Cause the Teacher object to call lunch on all // the objects on the list. missJones.callLunch(); }//end main() }//end class Callback04 //=======================================================// |