An important aspect of OOP programming is the ability of a subclass to replace an inherited method implementation with a new implementation especially appropriate to its instances. This is called overriding llo"q. a method. Sometimes, a class may introduce methods that every descendant class is expected to override. For example, SOMobject ves introduces the somPrintSelf method, and a good SOM programmer will generally override this method when implementing a new class.
The purpose of somPrintSelf is to print a brief description of an object. The method can be useful when debugging an application that deals with a number of objects of the same class -assuming the class designer has overridden somPrintSelf with a message that is useful in distinguishing different objects of the class. For example, the implementation of somPrintSelf provided by SOMobjects simply prints the class of the object and its address in memory. SOMclass overrides this method so that, when somPrintSelf is invoked on a class object, the name of the class will print.
This example illustrates how somPrintSelf might be overridden for the "Hello" class. An important identifying characteristic of "Hello" objects is the message they hold; thus, the following steps illustrate how somPrintSelf could be overridden in "Hello" to provide this information.
To override the somPrintSelf method in "Hello", additionalinformation must be provided in "hello.idl" in the form of an implementation statement, which gives extra information about the class, its methods and attributes, and any instance variables. (The previous examples omitted the optional "implementation" statement, because it was not needed.)
In the current example, the "implementation" statement introduces the modifiers for the "Hello" class, as follows.
#include <somobj.idl> interface Hello : SOMObject { void sayHello(); attribute string msg; #ifdef __SOMIDL__ implementation { //# Method Modifiers: somPrintSelf: override; // Override the inherited implementation of somPrintSelf. }; #endif };
Here, "somPrintSelf:" introduces a list of modifiers for the (inherited) somPrintSelf method in the class "Hello". Modifiers are like C/C ++ #pragma commands and give specific implementation details to the compiler. This example uses only one modifier, "override." Because of the "override" modifier, when somPrintSelf is invoked on an instance of class "Hello", Hello's implementation of somPrintSelf (in the implementation file) will be called, instead of the implementation inherited from the parent class, SOMObject.
The "#ifdef__SOMIDL__" and "#endif" are standard C and C++ preprocessor commands that cause the "implementation" statement to be read only when using the SOM IDL compiler (and not some other IDL compiler).
#include <hello.ih> SOM_Scope void SOMLINK sayHello(Hello somSelf, Environment *ev) { /* HelloData *somThis = HelloGetData(somSelf); */ HelloMethodDebug("Hello","sayHello"); printf("%s\n", __get_msg(somSelf, ev)); } SOM_Scope void SOMLINK somPrintSelf(Hello somSelf) { HelloData *somThis = HelloGetData(somSelf); HelloMethodDebug("hello","somPrintSelf"); Hello_parent_SOMObject_somPrintSelf(somSelf); }
Note that the SOM Compiler added code allowing the "Hello" class to redefine somPrintSelf. The SOM Compiler provides a default implementation for overriding the somPrintSelf method. This default implementation simply calls the "parent method" [the procedure that the parent class of "Hello" (SOMObject) uses to implement the somPrintSelf method]. This parent method call is accomplished by the macro Hello_parent_SOMObject_somPrintSelf defined in "hello.ih."
Notice that the stub procedure for overriding the somPrintSelf method does not include an Environment parameter. This is because somPrintSelf is introduced by SOMObject, which does not include the Environment parameter in any of its methods (to ensure backward compatibility). The signature for a method cannot change after it has been introduced.
Within the new somPrintSelf method procedure, display a brief description of the object, appropriate to "Hello" objects. Note that the parent method call is not needed, so it has been deleted. Also, direct access to instance data introduced by the "Hello" class is not required, so the assignment to "somThis" has been commented out (see the first line of the procedure).
SOM_Scope void SOMLINK somPrintSelf(Hello somSelf) { HelloData *somThis = HelloGetData(somSelf); HelloMethodDebug("Hello","somPrintSelf"); somPrintf("--a %s object at location %x with msg:s\n", _somGetClassName(somSelf), somSelf, __get_msg(somSelf,0)); }
For C programmers:
#include <hello.h> int main(int argc, char *argv[]) { Hello obj; Environment *ev = somGetGlobalEnvironment(); obj = HelloNew(); /* Set the msg text */ __set_msg(obj, ev, "Hi There"); /* Execute the "somPrintSelf" method */ _somPrintSelf(obj); _somFree(obj); return (0); }
For C++ programmers:
#include <hello.xh> int main(int argc, char *argv[]) { Hello *obj; Environment *ev = somGetGlobalEnvironment(); obj = new Hello; /* Set the msg text */ __setmsg(obj, ev, "Hi There"); /* Execute the "somPrintSelf" method */ obj->somPrintSelf(); obj->somFree(); return (0); }
> hello -- a Hello object at location 20062838 with msg: Hi There