7.4 Absolute position
The <absolute-position> class represents latitude and longitude. One way to represent latitude and longitude is with degrees, minutes, seconds, and a direction. We can use the approach of combining degrees, minutes, and seconds into a total-seconds slot as we did for <time>. We can also define a class that represents total seconds and a direction, and call it <directed-angle>:
define abstract class <directed-angle> (<object>) slot total-seconds :: <integer>, init-keyword: total-seconds:; slot direction :: <string>, init-keyword: direction:; end class <directed-angle>;
We use the <directed-angle> class in the definition of <absolute-position>:
define class <absolute-position> (<position>) slot latitude :: <directed-angle>, init-keyword: latitude:; slot longitude :: <directed-angle>, init-keyword: longitude:; end class <absolute-position>;
Modularity note: The |
Comparison to C: If you are familiar with a language that uses explicit pointers, such as C, you may be confused by Dylan's object model. Although there is no pointer-to operation in Dylan, there are pointers in the implementation. If you are trying to imagine how Dylan objects are implemented, think in terms of always manipulating a pointer to the object — a Dylan variable (or slot) stores a pointer to an object, rather than a copy of the object's slots. Similarly, assignment, argument passing, and identity comparison are in terms of pointers to objects. See Appendix B, Dylan Object Model for C and C++ Programmers. |
We could define the say method as follows:
define method say (position :: <absolute-position>) => ()
format-out("%d degrees %d minutes %d seconds %s latitude\n",
decode-total-seconds(position.latitude));
format-out("%d degrees %d minutes %d seconds %s longitude\n",
decode-total-seconds(position.longitude));
end method say;
The preceding method depends on decode-total-seconds having a method that is applicable to <directed-angle> (the type of the objects returned by position.latitude and position.longtude). We define such a method in Section 7.6.
Modularity note: The preceding |
The say method on <absolute-position> should not call format-out directly on the two instances of <directed-angle> stored in the latitude and longitude slots. Instead, we can define a say method on <directed-angle>, and can call it in the method on <absolute-position>:
define method say (angle :: <directed-angle>) => () let(degrees, minutes, seconds) = decode-total-seconds(angle); format-out("%d degrees %d minutes %d seconds %s", degrees, minutes, seconds, angle.direction); end method say; define method say (position :: <absolute-position>) => () say(position.latitude); format-out(" latitude\n"); say(position.longitude); format-out(" longitude\n"); end method say;
Modularity note: Our modularity is improved, now that the There is still a problem with this approach, because the |
We defined the <directed-angle> class to represent what latitude and longitude have in common. It is useful to recognize that latitude and longitude have differences as well as similarities. We represented latitude and longitude by the names of slots in <absolute-position>, and their implementations as instances of <directed-angle>. We can elevate the visibility of latitude and longitude by providing classes that represent each of them:
define class <latitude> (<directed-angle>) end class <latitude>; define class <longitude> (<directed-angle>) end class <longitude>;
We redefine <absolute-position> to use <latitude> and <longitude>:
define class <absolute-position> (<position>) slot latitude :: <latitude>, init-keyword: latitude:; slot longitude :: <longitude>, init-keyword: longitude:; end class <absolute-position>;
|
Figure 7.1 shows the inheritance relationships among the position and angle classes.
We define these new say methods:
define method say (latitude :: <latitude>) => ()
next-method();
format-out(" latitude\n");
end method say;
define method say (longitude :: <longitude>) => ()
next-method();
format-out(" longitude\n");
end method say;
The calls to next-method in the methods on <latitude> and <longitude> will call the method on <directed-angle>, shown on page 87.
We redefine the say method on <absolute-position>:
define method say (position :: <absolute-position>) => () say(position.latitude); say(position.longitude); end method say;
Modularity note: The approach of defining the classes
|





