call next method statement. G2 automatically calls the correct method based on the structure of the class hierarchy.
G2 methods have essentially the same syntax as ordinary G2 procedures. Both procedures and methods:
call or by start
call next method, while an ordinary procedure cannot.
vessel, with three subclasses: tank, bottle, and flask.
tank: Unscrew the tank's cap.
bottle: Remove the bottle's cork.
flask: Sterilize the flask.
Your code would need to know in advance which class of vessel is to be filled, and invoke a different procedure depending on the class, or else use a case statement that selects on class to choose the correct procedure dynamically. The former technique greatly constricts code flexibility. The latter is not too burdensome for three subclasses - but what if there were hundreds of them?
Filling Vessels Using Methods
To fill vessels by using methods, you could create a method for each of the four classes. Each of these methods would be similar to the analogous procedure, with the following differences.
fill.
tank, bottle, and class would use call next method to invoke the method for vessel.
Your code would not need to know the class of a vessel to be filled, or use a case statement that selects on class. With the above methods defined, you can invoke
fill on any tank, bottle, or flask. G2 then looks at the class of the vessel and invokes the fill method specific to that class. Thus fill means different things for different classes. This property of methods is called polymorphism.call next method, G2 scans the class hierarchy path of the relevant class, looking for a superior class that also has a fill method. The class vessel is the direct superior of tank, bottle, and flask, and defines a fill method. G2 invokes that method on the vessel. When the method returns, the lower-level method continues execution. Encapsulation
Methods allow existing code to be extended more easily than procedures do. Suppose that you now define a fourth subclass of vessel, say tube, which must be washed before it can be filled, and labeled afterwards. You need only define a fill method bound to tube, and code that method to:
call next method
fill method; not in the code that calls the method, which needs to know only the operation's name. This property of methods is called encapsulation.
Suppose that
vessel has another subclass, vial, that needs no preparation before filling and no cleanup afterwards. That is, filling a vial requires no customized behavior, but only the behavior characteristic of every vessel. The vial class would need no fill method of its own. If you invoked
fill on a vial, G2 would search vial's class inheritance path looking for a method named fill. The class vessel is the direct superior of vial, and defines a fill method. G2 invokes that method on the vial.G2 does the same thing every time you invoke a method, whether directly or with
call next method: it scans the class inheritance path of the relevant class, and invokes the first method it encounters that has the correct name and the right number of arguments. Since every class is the first element of its own class inheritance path, this technique gives a locally defined method precedence over any inherited method.