14.6.2 Subtype polymorphism. 4tH 4tH Forth compiler
광고
광고
CHAPTER 14. PREPROCESSOR LIBRARIES 247
14.6.2
Subtype polymorphism
”Polymorphism” is the ability of ”objects” belonging to different types to respond to ”method” or ”property” calls of the same name, each one according to an appropriate type-specific behavior. Ok, that’s a hard one to swallow. Let’s break it down. We now know that is
”class” is nothing more than a structure.
In section 11.15 we already learned we could extend a structure. You may not realize it, but you can pass a pointer to an extended structure to a word that takes a pointer to the unextended structure and manipulate any of the fields they share - without problems.
Of course, that includes fields that hold execution tokens. That is the basic principle of polymorphism.
Let’s investigate that one a but further. Lots of animals create sounds. Let’s make a ”class” for them:
:: Animal class virtual: Talk end-class {}
;
That’s all. A ”class” with one ”method”, no ”properties” and no ”binding”. You’d probably call it a ”class with uninitialized methods”, but in object orientation it is usually called an
”interface”. Even if you don’t initialize or bind anything you have to use curly braces in order to keep the stack balanced. You can also use ”{}”, which is shorthand for ”{ }”.
Ok, now we have an animal, let’s define a dog:
:: Dog extends Animal end-extends {
:virtual Talk { ." Woof" cr } ;method
}
;
The ”EXTENDS” word allows you to indicate from which class this type is derived - in this case an ”Animal”. In this case, we don’t add any ”properties” or ”methods”, but we do bind the previously defined method ”Talk”. We can do the same thing for a cat:
:: Cat extends Animal end-extends {
:virtual Talk { ." Meow" cr } ;method
}
;
If we now create a ”cat” object and a ”dog” object we can make them talk in their own perculiar way: static Cat MyCat static Dog MyDog
MyCat => Talk
MyDog => Talk
That’s what’s called ”dynamic dispatch”: when a method is invoked on an object, the object itself determines what code gets executed. You can take that a step further by defining e.g.
a figure:
CHAPTER 14. PREPROCESSOR LIBRARIES 248
:: figure class virtual: surface virtual: outline end-class {}
;
Yes, that’s an ”interface”. Now let’s define a rectangle:
\ define an empty class figure
\ with no properties and two
\ uninitialized methods
:: rectangle extends figure field: _width field: _height method: double
\ define a subtype rectangle
\ with two specific properties
\ and a private method end-extends {
\ now initialize surface and outline
:method double { 2* } ;method
:virtual surface { this -> _width @ this -> _height @ * } ;method
:virtual outline { this -> _width @ this -> double this -> _height @ this -> double +
} ;method
;
} private{ double } \ make method private
Note the method ”double” is private, which is means it can only be used within the class itself. That’s why we made it a ”static” method, because it’s not gonna be redefined any time soon. And let’s also define a circle while we’re at it:
:: circle extends figure field: radius
\ define a subtype circle
\ with one specific property
\ and a private method method: pi* end-extends {
\ now initialize surface and outline
:method pi* { 103993 33102 */ } ;method
:virtual surface { this -> radius @ dup * this -> pi* } ;method
:virtual outline { this -> radius @ 2* this -> pi* } ;method
\ make method private
;
} private{ pi* }
Both subclasses have very different properties, e.g. ”radius” has very little meaning in the context of a rectangle. However, they do share some methods, so if we instantiate them, we can ”ask” them to calculate their surface - or their outline: static rectangle MyRectangle static circle MyCircle
4 MyRectangle -> _width !
5 MyRectangle -> _height !
MyRectangle => surface . cr
MyRectangle => outline . cr
\ make a rectangle instance
\ make a circle instance
\ initialize the rectangle
\ use both methods
25 MyCircle -> radius !
MyCircle => surface . cr
MyCircle => outline . cr
Nothing to it - if you know what’s under the hood.
\ initialize the circle
\ use both methods
다운로드
광고