home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 14 Text / 14-Text.zip / SOM-NT.ZIP / SOM-NT.TXT
Text File  |  1992-09-23  |  36KB  |  911 lines

  1. Object-Oriented Programming in OS/2 2.0
  2. Using SOM
  3. by
  4. Roger Sessions
  5. Nurcan Coskun
  6. --------------------------------------------------------
  7. THIS ARTICLE WAS ORIGINALLY PUBLISHED IN THE PERSONAL
  8. SYSTEMS DEVELOPER WINTER 1992 AND IS COPYRIGHT BY IBM.
  9. THIS ARTICLE MAY NOT BE REPRINTED IN WHOLE OR IN PART
  10. WITHOUT PERMISSION.
  11.  
  12. ABSTRACT
  13. Object-Oriented Programming is quickly establishing itself as an
  14. important methodology in developing high quality, reusable code.
  15. In the 2.0 release of OS/2, IBM is introducing a new system for
  16. developing class libraries and Object-Oriented programs.  This
  17. system is called SOM for System Object Model.  This paper gives a
  18. general introduction to the Object-Oriented Paradigm, discusses
  19. developing Object-Oriented class libraries using SOM, and
  20. compares SOM libraries to those developed using standard Object-
  21. Oriented languages.
  22.  
  23. INTRODUCTION TO OBJECT-ORIENTED PROGRAMMING
  24. The latest revolution to hit the software community is Object-
  25. Oriented Programming.  Object-Oriented Programming Languages
  26. (OOPL) are being used throughout the industry, Object-Oriented
  27. Databases (OODB) are starting elicit widespread interest, and
  28. even Object-Oriented Design and Analysis (OODA) tools are
  29. changing the way people design and model systems.
  30.  
  31. Object-Oriented Programming is best understood in contrast to its
  32. close cousin, Structured Programming.  Both attempt to deal with
  33. the same basic issue, managing the complexity of ever more
  34. complex software systems.
  35.  
  36. Structured Programming models a system as a layered set of
  37. functional modules.  These modules are built up in a pyramid like
  38. fashion, each layer representing a higher level view of the
  39. system.  Structured Programming models the system's behavior, but
  40. gives little guidance to modeling the system's information.
  41.  
  42. Object-Oriented Programming models a system as a set of
  43. cooperating objects.  Like Structured Programming, it tries to
  44. manage the behavioral complexity of a system.  Object-Oriented
  45. Programming, however, goes beyond Structured Programming in also
  46. trying to manage the informational complexity of a system.
  47.  
  48. Because Object-Oriented Programming models both the behavioral
  49. and informational complexity of a system, the system tends to be
  50. much better organized than if it was simply well "structured".
  51. Because Object-Oriented systems are better organized, they are
  52. easier to understand, debug, maintain, and evolve.  Well
  53. organized systems also lend themselves to code reuse.
  54.  
  55. Object-Oriented Programming sees the dual issues of managing
  56. informational and behavioral complexity as being closely related.
  57. Its basic unit of organization is the object.  Objects have some
  58. associated data, which we call the object's state, and a set of
  59. behaviors, which we call the object's methods.  A class is a
  60. general description of an object, which defines the data which
  61. represents the object's state, and the methods the object
  62. supports.
  63.  
  64. OBJECT-ORIENTED PROGRAMMING IN C
  65. Before we examine SOM, let's consider Object-Oriented Programming
  66. in C; this will lead us naturally into the SOM philosophy.  The
  67. techniques in this section as well as many related advanced C
  68. coding techniques are discussed in the book Reusable Data
  69. Structures for C USessions, 89e.
  70.  
  71. Consider a data structure definition containing information
  72. related to a generic stack.  We may have a series of functions
  73. all designed to operate on our stack structure.  Given a basic
  74. stack definition, we may have multiple instances of this
  75. structure declared within our program.
  76.  
  77. Our generic stack definition, in C, might look like
  78.  
  79. struct stackType {
  80.   void *stackArrayUSTACK_SIZEe;
  81.   int stackTop;
  82. };
  83. typedef struct stackType Stack;
  84.  
  85. We could define some generic stack functions, say
  86.  
  87. Stack *create();       /* malloc and initialize a new stack. */
  88. void *pop(             /* Pop element off stack. */
  89.   Stack *thisStack);
  90. void push(             /* Push new element onto stack. */
  91.   Stack *thisStack,
  92.   void *nextElement);
  93.  
  94. Most C programmers can imagine how such functions would be
  95. written.  The push() function, for example, would look like
  96.  
  97. void push(Stack *thisStack, void *nextElement)
  98. {
  99.   thisStack->stackArrayUthisStack->stackTope = nextElement;
  100.   thisStack->stackTop++;
  101. }
  102.  
  103. A client program might use this stack to, say, create a stack of
  104. words needing interpretation:
  105.  
  106. main()
  107. {
  108.   Stack *wordStack;
  109.  
  110.   char *subject = "Emily";
  111.   char *verb = "eats";
  112.   char *object = "ice cream";
  113.   char *nextWord;
  114.  
  115.   wordStack = create();
  116.   push(wordStack, object);
  117.   push(wordStack, verb);
  118.   push(wordStack, subject);
  119.  
  120.   /* ... */
  121.   while (nextWord = pop(wordStack)) {
  122.     printf("%s\n", nextWord);
  123.     /* ... */
  124.   }
  125. }
  126.  
  127. Using this example, let's look at the language of Object-Oriented
  128. Programming.  A class is a definition of an object.  The
  129. definition includes the data elements of the object and the
  130. methods it supports.  A stack is an example of a class.  We say
  131. that a stack contains two data elements (stackArray and
  132. stackTop), and supports three methods, create(), push(), and
  133. pop().  A method is like a function, but is designed to operate
  134. on an object of a particular class.  An object is a specific
  135. instance, or instantiation, of a class.  We say wordStack is an
  136. object of class Stack, or wordStack is an instance of a stack.
  137.  
  138. Every method needs to know the specific object on which it is to
  139. operate.  We call this object the target object, or sometimes the
  140. receiving object.  Notice that each method (except create())
  141. takes as its first parameter a pointer to the target object.
  142. This is because a program may have many objects of a given class,
  143. and each are potential targets for the class methods.
  144.  
  145. There are three important advantages of this type of
  146. organization.  First, we are developing some generic concepts,
  147. which can be reused in other situations in which similar concepts
  148. are appropriate.  Second, we are developing self-contained code,
  149. which can be fully tested before it is folded into our program.
  150. Third, we are developing encapsulated code, the internal details
  151. of which are hidden and of no interest to the client.  Our client
  152. main() program need know nothing about the Stack class other than
  153. its name, the methods it supports,  and their interfaces.
  154.  
  155. INTRODUCTION TO SOM
  156. OS/2 2.0 includes a language-neutral Object-Oriented programming
  157. mechanism called SOM (for System Object Model).  Although it is
  158. possible to write Object-Oriented programs in traditional
  159. languages, such as we did with the stack example, SOM is
  160. specifically designed to support the new paradigm and to be
  161. usable with both procedural (or non Object-Oriented) languages
  162. and Object-Oriented languages.
  163.  
  164. A major claim of Object-Oriented programming is code reusability.
  165. This is most often achieved through the use of class libraries.
  166. Today's library technology is limited in that these class
  167. libraries are always language specific.  A C++ library cannot be
  168. used by a Smalltalk programmer, and visa versa.  Clearly there is
  169. a need to create a language-neutral object model, one which can
  170. be used to create class libraries usable from any programming
  171. language, procedural or Object-Oriented.  SOM is designed to
  172. address this need.
  173.  
  174. SOM introduces three important features lacking in most
  175. procedural languages.  These are encapsulation, inheritance, and
  176. polymorphism (referred to here as "override resolution").
  177.  
  178. Encapsulation means the ability to hide implementation details
  179. from clients.  This protects clients from changes in our
  180. implementation, and protects our implementation from tinkering by
  181. clients.  Our stack example was not protected.  Although clients
  182. did not need to know the internal data structures of the stack,
  183. we had no way to prevent clients from looking at such
  184. implementation details.  We could discourage, but not prevent,
  185. clients from writing code which used, and possibly corrupted,
  186. internal stack data elements.
  187.  
  188. Inheritance, or class derivation, is a specific technique for
  189. developing new classes from existing classes.  It allows one to
  190. create new classes which are more specialized versions of
  191. existing classes.  For example, we could create a
  192. DebuggableStack, which is like a Stack class, but supports
  193. further debugging methods, such as peek() and dump().
  194.  
  195. Inheritance also allows code consolidation.  If we have a class
  196. defining GraduateStudent and UnderGraduateStudent, we can
  197. consolidate common code into a third class, Student.  We then
  198. define GraduateStudent and UnderGraduate as more specialized
  199. classes, both derived from the common parent Student.
  200.  
  201. Inheritance introduces some additional semantics beyond those we
  202. have already examined.  A specialized class is said to be derived
  203. from a more generalized class.  The general class is called the
  204. parent class, or sometimes, the base class.  The specialized
  205. class is called the child class, or sometimes, the derived class.
  206. A child class is said to inherit the characteristics of its
  207. parent class, meaning that any methods defined for a parent are
  208. automatically defined for a child.  Thus because GraduateStudent
  209. and UnderGraduateStudent are both derived from Student, they both
  210. automatically acquire any methods declared in their common
  211. parent.
  212.  
  213. Override resolution means invoked methods are resolved based not
  214. only on the name of the method, but also on a class's place
  215. within a class hierarchy.  This allows us to redefine methods as
  216. we derive classes.  We might define a printStudentInfo() method
  217. for Student and then override, or redefine, the method in both
  218. UnderGraduateStudent, and GraduateStudent.  Override resolution
  219. means that the method is resolved based on the type of the target
  220. object.  If the target object type is a Student, the Student
  221. version of printStudentInfo() is invoked.  If the target object
  222. type is a GraduateStudent, the GraduateStudent version of
  223. printStudentInfo() is invoked.
  224.  
  225. We will now look at SOM in more detail by examining how classes
  226. are defined in SOM, how SOM methods are written in the C
  227. programming language, and how clients use SOM classes.  SOM will
  228. eventually allow developers to write methods in a variety of
  229. languages including the popular Object-Oriented programming
  230. languages.  In OS/2 2.0, SOM support is limited to C, thus the
  231. language used in the examples.
  232.  
  233. DEFINING CLASSES IN SOM
  234. The process of creating class libraries in SOM is a three step
  235. process.  The class designer defines the class interface,
  236. implements the class methods, and finally loads the resulting
  237. object code into a class library.  Clients either use these
  238. classes directly, make modifications to suit their specific
  239. purposes, or add entirely new classes of their own.
  240.  
  241. In SOM we define a class by creating a class definition file.  We
  242. will give a basic example here, and defer more detailed
  243. discussion of the many keywords and options to the SOM manuals
  244. USOMe.
  245.  
  246. The class definition file is named with an extension of "csc".
  247. In its most basic form, the class definition file is divided into
  248. the following sections:
  249.  
  250.   1. Include section
  251.      This section declares files which need to be included, much
  252.      like the C #include directive.
  253.   2. Class name and options
  254.      This section defines the name of the class and declares
  255.      various options.
  256.   3. Parent information
  257.      This defines the parent, or base, class for this class.  All
  258.      classes must have a parent.  If your class is not derived
  259.      from any of your own classes, than it's parent will be the
  260.      SOM defined class SOMObject, the class information of which
  261.      is in the file somobj.sc.
  262.   4. Data Section
  263.      This section declares any data elements contained by objects
  264.      of this class.  By default, data can be accessed only by
  265.      methods of the class.
  266.   5. Methods Section
  267.      This section declares methods to which objects of this class
  268.      can respond.  By default, all methods declared in this
  269.      section are available to any class client.
  270.  
  271. Comments can be used for documentation purposes, and the
  272. following styles are all acceptable:
  273.  
  274. /* This is a comment. */
  275. // This is a comment.
  276. -- This is a comment.
  277.  
  278. The class definition file, student.csc, describes a non-derived
  279. Student class, and is shown in figure 1.
  280.  
  281. ((start figure 1, caption: Class Definition File: student.csc))
  282. include <somobj.sc>
  283.  
  284. class:
  285.   Student;
  286.  
  287. -- "Student" class provides a base class to generate more
  288. -- specialized students like "GraduateStudent" and
  289. -- "UnderGraduateStudent".
  290.  
  291. parent:
  292.   SOMObject;
  293.  
  294. data:
  295.   char  idU16e;      /* student id */
  296.   char  nameU32e;    /* student name */
  297.  
  298. methods:
  299.  
  300.   void  setUpStudent(char *id, char *name);
  301.   -- sets up a new student.
  302.  
  303.   void  printStudentInfo();
  304.   -- prints the student information.
  305.  
  306.   char  *getStudentType();
  307.   -- returns the student type.
  308.  
  309.   char  *getStudentId();
  310.   -- returns the student id.
  311. ((end table))
  312.  
  313. WRITING METHODS
  314. Class methods are implemented in the class method implementation
  315. file.  Each method defined in the method section of the class
  316. definition file needs to be implemented.  They can be implemented
  317. in any language that offers SOM support, which for now is only C.
  318. The student class method implementation file, student.c, is shown
  319. in figure 2.
  320.  
  321. ((start figure 2, caption: Class Method Implementation File:
  322. student.c))
  323. #define Student_Class_Source
  324. #include "student.ih"
  325.  
  326. static void setUpStudent(
  327.     Student *somSelf, char *id, char *name)
  328. {
  329.     StudentData *somThis = StudentGetData(somSelf);
  330.     strcpy(_id, id);
  331.     strcpy(_name, name);
  332. }
  333. static void printStudentInfo(Student *somSelf)
  334. {
  335.     StudentData *somThis = StudentGetData(somSelf);
  336.     printf("    Id         : %s \n", _id);
  337.     printf("    Name       : %s \n", _name);
  338.     printf("    Type       : %s \n", _getStudentType(somSelf));
  339. }
  340. static char *getStudentType(Student *somSelf)
  341. {
  342.     StudentData *somThis = StudentGetData(somSelf);
  343.     static char *type = "student";
  344.     return (type);
  345. }
  346. static char *getStudentId(Student *somSelf)
  347. {
  348.     StudentData *somThis = StudentGetData(somSelf);
  349.     return (_id);
  350. }
  351. ((end figure 2))
  352.  
  353. Notice that the method code looks much like standard C, with a
  354. few differences.
  355.  
  356. First, each method takes, as its first parameter, a pointer
  357. (somSelf) to the target object.  This is very similar to our C
  358. stack implementation.  This parameter is implicit in the class
  359. definition file, but is made explicit in the method
  360. implementation.
  361.  
  362. Second, each method starts with a line setting an internal
  363. variable named somThis, which is used by macros within the SOM
  364. header file.
  365.  
  366. Third, names of data elements of the target object are preceded
  367. by an underscore character.  The underscored name turns into a C
  368. language macro defined in the class header file, part of the
  369. package SOM offers to shield method developers from the details
  370. of memory layout.
  371.  
  372. Fourth, methods are invoked using an underscored syntax.  This
  373. underscored name turns into a macro invocation which shields
  374. programmers from having to understand the details of method
  375. resolution.
  376.  
  377. The first parameter of every method is always a pointer to the
  378. target object.  This can be seen in the method printStudentInfo()
  379. which invokes the method getStudentType() on its own target
  380. object.
  381.  
  382. The process of creating a class method implementation file can be
  383. greatly speeded up by the SOM compiler, which creates a valid C
  384. method implementation file lacking only the body of the methods.
  385. The body is then filled in by the class implementor. For the
  386. student example, the SOM compiler would create a file similar to
  387. the one shown in figure 3.
  388.  
  389. ((start figure 3, caption: SOM compiler generated student.c))
  390. #define Student_Class_Source
  391. #include "student.ih"
  392.  
  393. static void setUpStudent(
  394.     Student *somSelf, char *id, char *name)
  395. {
  396.     StudentData *somThis = StudentGetData(somSelf);
  397. }
  398. static void printStudentInfo(Student *somSelf)
  399. {
  400.     StudentData *somThis = StudentGetData(somSelf);
  401. }
  402. /* ...and so on for the other methods. */
  403. ((end figure 3))
  404.  
  405. MECHANICS OF USING SOM
  406. There is a set of files involved with each class.  Here we will
  407. look at the most important of these files and discuss their
  408. purpose and how they are created.  They have different
  409. extensions, but all have the same filename as the class
  410. definition file, Student in our example.  The SOM compiler
  411. generates files based on the value of an environment variable, as
  412. described in the SOM users guide USOMe.  These files are
  413. described in table 1.
  414.  
  415. ((start table 1, caption: Student Class Files))
  416. student.csc - This is the class definition file, as described
  417. earlier.
  418.  
  419. student.sc - This is a subset of the class definition file.  It
  420. includes all information from the .csc file which is public,
  421. including comments on public elements.  For the student example,
  422. student.sc would include everything from student.csc except the
  423. data section.  This file is created by the SOM compiler, and
  424. although human readable, should not be edited, as it will be
  425. regenerated whenever changes are made to the .csc file.
  426.  
  427. student.h - This is a valid C header file which contains macros
  428. necessary to invoke public methods and access public data
  429. elements of the class.  This file will be included in any client
  430. of the class.  This file is created by the SOM compiler, and is
  431. normally only read by programmers who need to know how method
  432. resolution is implemented.  This file should not be edited.
  433.  
  434. student.ih - Similar to student.h, but contains additional
  435. information needed for implementing methods.  This is the
  436. implementor's version of the .h file, and must be included in the
  437. class methods implementation file.  This file is created by the
  438. SOM compiler and should not be edited.
  439.  
  440. student.c - Contains the method implementations.  This is
  441. initially created by the SOM compiler and then updated by the
  442. class implementor.
  443. ((end table1)
  444.  
  445. BUILDING SOM CLASSES FROM OTHER CLASSES
  446. There are two ways to use classes as building blocks for other
  447. classes.  These are derivation (or inheritance) and construction.
  448. Let's consider derivation first.
  449.  
  450. In this example, GraduateStudent is derived from Student, its
  451. base, or parent class.  A derived class automatically picks up
  452. all characteristics of the base class.  A derived class can add
  453. new functionality through the definition and implementation of
  454. new methods.  A derived class can also redefine methods of its
  455. base class, a process called overriding.  GraduateStudent adds
  456. setUpGranduateStudent() to those methods it inherits from
  457. Student.  It overrides two other inherited methods,
  458. printStudentInfo() and getStudentType().  It inherits without
  459. change setUpStudent() and getStudentId() from the Student base
  460. class.
  461.  
  462. The class definition file for GraduateStudent, graduate.csc, is
  463. shown in figure 4.
  464.  
  465. ((start figure 4, caption: Class Definition File: graduate.csc))
  466.  
  467. include <student.sc>
  468.  
  469. class:
  470.   GraduateStudent;
  471.  
  472. parent:
  473.   Student;
  474.  
  475. data:
  476.   char  thesisU128e;    /* thesis title */
  477.   char  degreeU16e;     /* graduate degree type */
  478.  
  479. methods:
  480.   override  printStudentInfo;
  481.   override  getStudentType;
  482.   void  setUpGraduateStudent(
  483.         char *id, char *name, char *thesis, char *degree);
  484. ((end figure 4))
  485.  
  486. The method implementation file, graduate.c, is shown in figure 5.
  487. ((start figure 5, caption: Class Method Implementation File:
  488. graduate.c))
  489.  
  490. #define GraduateStudent_Class_Source
  491. #include "graduate.ih"
  492.  
  493. static void printStudentInfo(GraduateStudent *somSelf)
  494. {
  495.     GraduateStudentData *somThis =
  496. GraduateStudentGetData(somSelf);
  497.     parent_printStudentInfo(somSelf);
  498.     printf("    Thesis     : %s \n", _thesis);
  499.     printf("    Degree     : %s \n", _degree);
  500. }
  501. static char *getStudentType(GraduateStudent *somSelf)
  502. {
  503.     static char *type = "Graduate";
  504.     return (type);
  505. }
  506. static void setUpGraduateStudent(
  507.     GraduateStudent *somSelf, char *id, char *name,
  508.     char *thesis, char *degree)
  509. {
  510.     GraduateStudentData *somThis =
  511. GraduateStudentGetData(somSelf);
  512.     _setUpStudent(somSelf,id,name);
  513.     strcpy(_thesis, thesis);
  514.     strcpy(_degree, degree);
  515. }
  516. ((end figure 5))
  517.  
  518. Often an overridden method will need to invoke the original
  519. method of its parent.  For example, the printStudentInfo() for
  520. GraduateStudent first invokes the Student version of
  521. printStudentInfo() before printing out the GraduateStudent
  522. specific information.  The syntax for this is
  523. "parent_MethodName", as can be seen in the printStudentInfo()
  524. method.
  525.  
  526. A given base class can be used for more than one derivation.  The
  527. class, UnderGraduateStudent, is also derived from Student.  The
  528. class definition file, undgrad.csc, is shown in figure 6.
  529.  
  530. ((start figure 6, caption: Class Definition File: undgrad.csc))
  531. include <student.sc>
  532.  
  533. class:
  534.   UnderGraduateStudent;
  535.  
  536. parent:
  537.   Student;
  538.  
  539. data:
  540.   char  dateU16e;     /* graduation date */
  541.  
  542. methods:
  543.   override  printStudentInfo;
  544.   override  getStudentType;
  545.   void  setUpUnderGraduateStudent(
  546.         char *id, char *name, char *date);
  547. ((end figure 6))
  548.  
  549. The method implementation file, undgrad.c, is shown in figure 7.
  550.  
  551. ((start figure 7, caption: Class Method Implementation File:
  552. undgrad.c))
  553.  
  554. #define UnderGraduateStudent_Class_Source
  555. #include "undgrad.ih"
  556.  
  557. static void printStudentInfo(
  558.     UnderGraduateStudent *somSelf)
  559. {
  560.     UnderGraduateStudentData *somThis =
  561.        UnderGraduateStudentGetData(somSelf);
  562.     parent_printStudentInfo(somSelf);
  563.     printf("    Grad Date  : %s \n", _date);
  564. }
  565. static char *getStudentType(UnderGraduateStudent *somSelf)
  566. {
  567.     static char *type = "UnderGraduate";
  568.     return (type);
  569. }
  570. static void setUpUnderGraduateStudent(
  571.     UnderGraduateStudent *somSelf,char *id, char *name, char
  572. *date)
  573. {
  574.     UnderGraduateStudentData *somThis =
  575.        UnderGraduateStudentGetData(somSelf);
  576.     _setUpStudent(somSelf,id,name);
  577.     strcpy(_date, date);
  578. }
  579. ((end figure 7))
  580.  
  581. The second technique for building classes is construction.  This
  582. means that a class uses another class, but not through
  583. inheritance.  A good example of construction is the class Course
  584. which includes an array of pointers to Students.  Each pointer
  585. contains the address of a particular student taking the course.
  586. We say that Course is constructed from Student.  The class
  587. definition file for Course, course.csc, is shown in figure 8.
  588.  
  589. ((start figure 8, caption: Class Definition File: course.csc))
  590. include <somobj.sc>
  591.  
  592. class:
  593.   Course;
  594.  
  595. -- "Course" class describes the interfaces required to setup the
  596. -- course information. The students are "Student" class type and
  597. -- can be added to or dropped from the courses through the
  598. -- "addStudent" and "dropStudent" methods.
  599.  
  600. parent:
  601.   SOMObject;
  602.  
  603. data:
  604.   char    codeU8e;         /* course code number */
  605.   char    titleU32e;       /* course title */
  606.   char    instructorU32e;  /* instructor teaching */
  607.   int     credit;            /* number of credits  */
  608.   int     capacity;          /* maximum number of seats */
  609.   Student *studentListU20e;/* enrolled student list */
  610.   int     enrollment;        /* number of enrolled students */
  611.  
  612. methods:
  613.   override  somInit;
  614.  
  615.   void  setUpCourse(char *code, char *title,
  616.      char *instructor, int credit, int capacity);
  617.   -- sets up a new course.
  618.  
  619.   int   addStudent(Student *student);
  620.   -- enrolls a student to the course.
  621.  
  622.   void  dropStudent(char *studentId);
  623.   -- drops the student from the course.
  624.  
  625.   void  printCourseInfo();
  626.   -- prints course information.
  627. ((end figure 8))
  628.  
  629. Often classes will want to take special steps to initialize their
  630. instance data.  An instance of Course must at least initialize
  631. the enrollment data element, to ensure the array index starts in
  632. a valid state.  The method somInit() is always called when a new
  633. object is created.  This method is inherited from SOMObject, and
  634. can be overridden when object initialization is desired.
  635.  
  636. This example brings up an interesting characteristic of
  637. inheritance, the "is-a" relationship between derived and base
  638. classes.  Any derived class can be considered as a base class.
  639. We say that a derived class "is-a" base class. In our example,
  640. any GraduateStudent "is-a" Student, and can be used anyplace we
  641. are expecting a Student.  The converse is not true.  A base class
  642. is not a derived class.  A Student can not be treated
  643. unconditionally as a GraduateStudent.  Thus elements of the array
  644. studentList can point to either Students, a GraduateStudents, or
  645. a UnderGraduateStudents.
  646.  
  647. The method implementation file for Course, course.c, is shown in
  648. figure 9.
  649.  
  650. ((start figure 9, caption: Class Method Implementation File:
  651. course.c))
  652. #define Course_Class_Source
  653. #include <student.h>
  654. #include "course.ih"
  655.  
  656. static void somInit(Course *somSelf)
  657. {
  658.     CourseData *somThis = CourseGetData(somSelf);
  659.     parent_somInit(somSelf);
  660.     _codeU0e = _titleU0e = _instructorU0e = '\0';
  661.     _credit = _capacity = _enrollment = 0;
  662. }
  663. static void setUpCourse(Course *somSelf, char *code,
  664.     char *title, char *instructor, int credit, int capacity)
  665. {
  666.     CourseData *somThis = CourseGetData(somSelf);
  667.     strcpy(_code, code);
  668.     strcpy(_title, title);
  669.     strcpy(_instructor, instructor);
  670.     _credit = credit;
  671.     _capacity = capacity;
  672. }
  673. static int addStudent(Course *somSelf, Student *student)
  674. {
  675.     CourseData *somThis = CourseGetData(somSelf);
  676.     if(_enrollment >= _capacity)  return(-1);
  677.     _studentListU_enrollment++e = student;
  678.     return(0);
  679. }
  680. static void dropStudent(Course *somSelf, char *studentId)
  681. {
  682.     int i;
  683.     CourseData *somThis = CourseGetData(somSelf);
  684.     for(i=0; i<_enrollment; i++)
  685.       if(!strcmp(studentId, _getStudentId(_studentListUie))) {
  686.         _enrollment--;
  687.         for(i; i<_enrollment; i++)
  688.           _studentListUie = _studentListUi+1e;
  689.         return;
  690.       }
  691. }
  692. static void printCourseInfo(Course *somSelf)
  693. {
  694.     int i;
  695.     CourseData *somThis = CourseGetData(somSelf);
  696.     printf("  %s %s \n", _code, _title);
  697.     printf("  Instructor Name : %s \n", _instructor);
  698.     printf("  Credit = %d, Capacity = %d, Enrollment = %d \n\n",
  699.              _credit, _capacity, _enrollment);
  700.     printf("  STUDENT LIST: \n\n");
  701.     for(i=0; i<_enrollment; i++) {
  702.       _printStudentInfo(_studentListUie);
  703.       printf("\n");
  704.     }
  705. }
  706. ((end figure 9))
  707.  
  708. Notice in particular the method printCourseInfo().  This method
  709. goes through the array studentList invoking the method
  710. printStudentInfo() on each student.  This method is defined for
  711. Student, and then overridden by both GraduateStudent and
  712. UnderGraduateStudent.  Since the array element can point to any
  713. of these three classes, we can't tell at compile time what the
  714. actual type of the target object is, only that the target object
  715. is either a Student or some type derived from Student.  Since
  716. each of these classes defines a different printStudentInfo()
  717. method, we don't know which of these methods will be invoked with
  718. each pass of the loop.  This is all under the control of override
  719. resolution.
  720.  
  721. THE SOM CLIENT
  722. Now let's see how a client might make use of these four classes
  723. in a program.  As we look at the program example shown in figure
  724. 10, we can discuss how objects are instantiated, or created, in
  725. SOM, and how methods are invoked.
  726.  
  727. ((start figure 10, caption: SOM client code))
  728. #include <student.h>
  729. #include <course.h>
  730. #include <graduate.h>
  731. #include <undgrad.h>
  732. main()
  733. {
  734.   Course *course = CourseNew();
  735.   GraduateStudent *jane = GraduateStudentNew();
  736.   UnderGraduateStudent *mark = UnderGraduateStudentNew();
  737.   _setUpCourse(course, "303", "Compilers ",
  738.      "Dr. David Johnson", 3, 15);
  739.   _setUpGraduateStudent(jane,"423538","Jane Brown",
  740.      "Code Optimization","Ph.D.");
  741.   _setUpUnderGraduateStudent(mark,"399542",
  742.      "Mark Smith", "12/17/92");
  743.   _addStudent(course, jane);
  744.   _addStudent(course, mark);
  745.   _printCourseInfo(course);
  746. }
  747. ((end figure 10))
  748.  
  749. A class is instantiated with the method classNameNew(), which is
  750. automatically defined by SOM for each recognized class.  Methods
  751. are invoked by clients just as they are inside SOM methods, and
  752. very similarly to our earlier C examples.  The first parameter is
  753. the target object.  The remaining parameters are whatever
  754. information is needed by the method.  The only odd feature is the
  755. underscore preceding the method name, which turns what looks like
  756. a regular function call into a macro defined in the .h file.
  757.  
  758. When run, the client program gives the output shown in figure 11.
  759.  
  760. ((start figure 11, caption: Client Program Output))
  761.  
  762.   303 Compilers
  763.   Instructor Name : Dr. David Johnson
  764.   Credit = 3, Capacity = 15, Enrollment = 2
  765.  
  766.   STUDENT LIST:
  767.  
  768.     Id         : 423538
  769.     Name       : Jane Brown
  770.     Type       : Graduate
  771.     Thesis     : Code Optimization
  772.     Degree     : Ph.D.
  773.  
  774.     Id         : 399542
  775.     Name       : Mark Smith
  776.     Type       : UnderGraduate
  777.     Grad Date  : 12/17/92
  778. ((end figure 11))
  779.  
  780. In the client program output we can see the override resolution
  781. at work in the different styles of displaying UnderGraduates and
  782. GraduateStudents.  A Course thinks of itself as containing an
  783. array of Students, and knows that any Student responds to a
  784. printStudentInfo() method.  But the printStudentInfo() method
  785. that a UnderGraduate responds to is different than the
  786. printStudentInfo() method that a GraduateStudent responds to, and
  787. the two methods give different outputs.
  788.  
  789. COMPARISON TO C++
  790. In this section we will compare some SOM features to those of the
  791. most widespread Object-Oriented programming language, C++,
  792. developed by Bjarne Stroustrup.  Some good introductory books
  793. about Object-Oriented programming in C++ are Class Construction
  794. in C and C++ USessions, 91e, The C++ Programming Language
  795. UStroustrupe, and C++ Primer ULippmane.
  796.  
  797. SOM has many similarities to C++.  Both support class
  798. definitions, inheritance, and overridden methods (called virtual
  799. methods in C++).  Both support the notion of encapsulation.  But
  800. whereas C++ is designed to support standalone programming
  801. efforts, SOM is primarily focused on the support of commercial
  802. quality class libraries.  Most of the differences between SOM and
  803. C++ hinge on this issue.
  804.  
  805. C++ class libraries are version dependent, while SOM class
  806. libraries are version independent.  When a new C++ class library
  807. is released, client code has to be fully recompiled, even if the
  808. changes are unrelated to public interfaces.  This problem is
  809. discussed in detail in the book Class Construction in C and C++
  810. USessions, 91e.  SOM, unlike C++, directly supports the
  811. development of upwardly compatible class libraries.
  812.  
  813. C++ supports programming in only one language, C++.  SOM is
  814. designed to support many languages (although in this first
  815. release it supports only C).  Rather than a language, SOM is
  816. really a system for defining, manipulating, and releasing class
  817. libraries.  SOM is used to define classes and methods, but it is
  818. left up to the implementor to choose a language for implementing
  819. methods.  Most programmers will therefore be able to use SOM
  820. quickly without having to learn a new language syntax.
  821.  
  822. C++ provides minimal support for implementation hiding, or
  823. encapsulation.  C++ class definitions, which must be released to
  824. clients, typically include declarations for the private data and
  825. methods.  This information is, at best, unnecessarily detracting,
  826. and at worst, proprietary.  In SOM, the client never has to see
  827. such implementation details.  The client need see only the .sc
  828. files, which by definition contain only public information.
  829.  
  830. C++ has limited means of method resolution.  SOM offers several
  831. alternatives.  Like C++, SOM supports offset method resolution,
  832. meaning that each method is represented by a method pointer which
  833. is set once and for all at compile time.  Unlike C++, SOM also
  834. offers facilities for resolving methods at run time.  Name Lookup
  835. resolution allows a client to ask for a pointer to a method by
  836. method name.  Dispatch resolution allows a client to package
  837. parameters at run time for dispatching to a method, a technique
  838. which allows SOM to be integrated into interpreted languages,
  839. such as Smalltalk.
  840.  
  841. One other interesting difference between SOM and C++ is in their
  842. notion of class.  In C++, the class declaration is very similar
  843. to a structure declaration.  It is a compile-time package with no
  844. characteristics that have significance at runtime.  In SOM, the
  845. class of an object is an object in its own right.  This object is
  846. itself an instantiation of another class, called the metaclass.
  847. The class object supports a host of useful methods which have no
  848. direct parallels in C++, such as somGetName(), somGetParent(),
  849. and somFindMethod().
  850.  
  851. SUMMARY
  852. A new Object Modeling System is introduced in OS/2 2.0. This
  853. object model is called The System Object Model, or SOM.  SOM is a
  854. dynamic object model which can provide useful class information
  855. about objects at run time. The goal of SOM is to support the
  856. development of class libraries useful by both compiled and
  857. interpreted languages.
  858.  
  859. ACKNOWLEDGEMENTS
  860. SOM is the work of many people.  Mike Conner developed the
  861. initial idea and implementation, and continues to lead the
  862. overall design of SOM.  Andy Martin designed the SOM Class
  863. Interface Language, and designed and implemented the class
  864. Interface compiler.  Larry Raper implemented many features of the
  865. run time library and ported SOM to OS/2.  Larry Loucks provided
  866. close technical tracking and was instrumental in focusing the
  867. effort.  Early SOM users who contributed much to the evolution of
  868. SOM include Nurcan Coskun, Hari Madduri, Roger Sessions, and John
  869. Wang.  The project is managed by Tony Dvorak.
  870.  
  871. BIBLIOGRAPHY
  872. ULippmane Stanley B. Lippman: C++ Primer, Second Edition.
  873. Addison-Wesley, Reading, Massachusetts, 1989.
  874.  
  875. USessions, 89e Roger Sessions: Reusable Data Structures for C.
  876. Prentice-Hall, Englewood Cliffs, New Jersey, 1989.
  877.  
  878. USessions, 91e Roger Sessions: Class Construction in C and C++,
  879. Object-Oriented Programming Fundamentals. Prentice-Hall,
  880. Englewood Cliffs, New Jersey, 1991 (in press).
  881.  
  882. USOMe Tentative Title: System Object Model Users Guide.  IBM
  883. Publication, 1991 (in preparation).
  884.  
  885. UStroustrupe Bjarne Stroustrup: The C++ Programming Language,
  886. Second Edition.  Addison-Wesley, Reading, Massachusetts, 1991.
  887.  
  888. BIOGRAPHIES
  889. Nurcan Coskun, IBM, 11400 Burnet Road, Austin, TX 78758
  890. Nurcan Coskun has a B.S. in Industrial Engineering from Middle
  891. East Technical University, an M.S. and a Ph.D. in Computer
  892. Science from University of Missouri-Rolla.  Her expertise is in
  893. integrated programming environments, code generators, incremental
  894. compilers, interpreters, language based editors, symbolic
  895. debuggers, application frameworks, and language design.  She is
  896. now working on Object-Oriented programming environments and
  897. previously worked on the OS/2 Database Manager.  Nurcan can be
  898. contacted at nurcan@ausvm1.iinus1.ibm.com
  899.  
  900. Roger Sessions, IBM, 11400 Burnet Road, Austin, TX 78758
  901. Roger Sessions has a B.A. in Biology from Bard College and an
  902. M.E.S. in Database Systems from the University of Pennsylvania.
  903. He is the author of two books, Reusable Data Structures for C,
  904. and Class Construction in C and C++, and several articles.  He is
  905. working on Object-Oriented programming environments and
  906. previously worked with high performance relational databases and
  907. Object-Oriented storage systems.  Roger can be contacted at
  908. sessions@ausvm1.iinus1.ibm.com.
  909.  
  910.  
  911.