For an example, see implicitinvocation.OverfullEvent. The actual events are usually quite simple; in order to use an OverfullEvent in the code, you would use something like:
OverfullEvent oe = new OverfullEvent(section); oe.announce();
These delivery objects know both about the type of the event and of the method to invoke in the recipient object. This object will only be called with the correct types of objects, but must cast the objects into the correct type before it can use their methods.
With this decoupling, the actual components don't need to know about the events. For example, if something will respond to an OverfullEvent, the component that will deal with it only needs to know what section is full, and should not need to know which event just took place. All knowledge of the event is in the Delivery object.