Java Cookbook, Second Edition
Problem
You want to provide callbacks , that is, have unrelated classes call back into your code. Solution
One way is to use a Java interface. Discussion
An interface is a class-like entity that can contain only abstract methods and final fields. As we've seen, interfaces are used a lot in Java! In the standard API, the following are a few of the commonly used interfaces:
Suppose we are generating a futuristic building management system. To be energy-efficient, we want to be able to remotely turn off (at night and on weekends) such things as room lights and computer monitors, which use a lot of energy. Assume we have some kind of "remote control" technology. It could be a commercial version of BSR's house-light control technology X10, it could be Bluetooth or 802.11 it doesn't matter. What matters is that we have to be very careful what we turn off. It would cause great ire if we turned off computer processors automatically people often leave things running overnight. It would be a matter of public safety if we ever turned off the building emergency lighting.[1] [1] Of course these lights wouldn't have remote power-off. But the computers might, for maintenance purposes. So we've come up with the design shown in Figure 9-1. Figure 9-1. Classes for a building management system
The code for these classes is not shown (it's pretty trivial) but it's in the online source. The top-level classes BuildingLight and Asset are abstract classes. You can't instantiate them, as they don't have any specific functionality. To ensure both at compile time and at runtime that we can never switch off the emergency lighting, we need only ensure that the class representing it, EmergencyLight, does not implement the PowerSwitchable interface. Note that we can't very well use direct inheritance here. No common ancestor class includes both ComputerMonitor and RoomLights that doesn't also include ComputerCPU and EmergencyLight. Use interfaces to define functionality in unrelated classes. How we use these is demonstrated by the BuildingManagement class; this class is not part of the hierarchy shown in Figure 9-1, but instead uses a collection (actually an array, to make the code simpler for illustrative purposes) of Asset objects from that hierarchy. Items that can't be switched must nonetheless be in the database, for various purposes (auditing, insurance, and so on). In the method that turns things off, the code is careful to check whether each object in the database is an instance of the PowerSwitchable interface. If so, the object is casted to PowerSwitchable so that its powerDown( ) method can be called. If not, the object is skipped, thus preventing any possibility of turning out the emergency lights or shutting off a machine that is busy running Seti@Home, downloading a big MP3 playlist, or performing system backups. /** * BuildingManagement - control an energy-saving building. * This class shows how we might control the objects in an office * that can safely be powered off at nighttime to save energy - lots of * it, when applied to a large office! */ public class BuildingManagement { Asset things[] = new Asset[24]; int numItems = 0; /** goodNight is called from a timer Thread at 2200, or when we * get the "shutdown" command from the security guard. */ public void goodNight( ) { for (int i=0; i<things.length; i++) if (things[i] instanceof PowerSwitchable) ((PowerSwitchable)things[i]).powerDown( ); } // goodMorning( ) would be the same, but call each one's powerUp( ). /** Add an Asset to this building */ public void add(Asset thing) { System.out.println("Adding " + thing); things[numItems++] = thing; } /** The main program */ public static void main(String[] av) { BuildingManagement b1 = new BuildingManagement( ); b1.add(new RoomLights(101)); // control lights in room 101 b1.add(new EmergencyLight(101)); // and emerg. lights. // add the computer on desk#4 in room 101 b1.add(new ComputerCPU(10104)); // and its monitor b1.add(new ComputerMonitor(10104)); // time passes, and the sun sets... b1.goodNight( ); } } When you run this program, it shows all the items being added, but only the PowerSwitchable ones being switched off: > java BuildingManagement Adding RoomLights@2dc77f32 Adding EmergencyLight@2e3b7f32 Adding ComputerCPU@2e637f32 Adding ComputerMonitor@2f1f7f32 Dousing lights in room 101 Dousing monitor at desk 10104 > |