; From: Dat Thuc Nguyen
; Date: Tue, 27 Apr 1999 20:35:16 +0000
; Subject: Script: Multiple Inheritance in C-Kermit OOP
; URL: http://www.smalltickle.com
;
; Multiple inheritance enriches software design.
; Not all OOP languages have it: C++ does; Java, Smalltalk don't.
; The following script implements multiple inheritance in C-Kermit.
; The famous animal class found in many C++ and Smalltalk references
; is used to present the subject.
;
; The Mammal class of animal has three data members: age, color, kind;
; and three member functions: kind, age, color, and destroy.
;
; The Endangered class of animal has one member data: category, and
; two member functions: category and destroy.
;
; The Bear class of animal derives from the Mammal class.  It overrides
; the member function: destroy, and supplies one more member function:
; favorite_food.
;
; The Panda class of animal is a multiple inheritance of the Bear and
; the Endangered classes, it overrides the function: destroy.
;
; The proper usage of the following elements in C-Kermit:
;    assign, _assign, define, _define, \v(macro)
; creates the OOP mechanisms:
;    polymorphism, overriding method, late binding.
;
; The syntax of Smalltalk in message invocation is applied here to
; reduce code and simplify class evolution.
;
; In the multiple derived class, the selection of the member functions
; of the super classes can be determined or overridden. This flexibility
; does not even exist in any of the OOP languages mentioned above.

;**************************************************
;*   DEFINITION OF THE CLASS MAMMAL               *
;**************************************************
define Mammal {
; \%1 name of the new Mammal
; \%2 age of the new Mammal
; \%3 color of the new Mammal
; kind is supplied by the derived class
     _assign Mammal::\%1.age \%2
     _assign Mammal::\%1.color \%3
     _define \%1 {
          if define \m(Mammal::\%1) {
               Mammal::\%1 \v(macro) {\%2} {\%3} {\%4}
          } else {
               return doesNotUnderstand
          }
     }
}

;**************************************************
;*   PUBLIC USAGE INTERFACE OF THE CLASS MAMMAL   *
;**************************************************
define Mammal::kind {
     echo \m(Mammal::\%1.kind)
}
define Mammal::age {
     echo \m(Mammal::\%1.age)
}
define Mammal::color {
     echo \m(Mammal::\%1.color)
}
define Mammal::destroy {
     _define Mammal::\%1.kind
     _define Mammal::\%1.age
     _define Mammal::\%1.color
     _define \%1
}

;**************************************************
;*   DEFINITION OF THE CLASS BEAR                 *
;**************************************************
define Bear {
; \%1 name of the new Bear
; \%2 age of the new Bear
; \%3 color of the new Bear
     Mammal Mammal::\%1 \%2 \%3
     _assign Mammal::Mammal::\%1.kind \v(macro)
     _define \%1 {
          local \%r
          if define \m(Bear::\%1) {
               Bear::\%1 \v(macro) \%2 \%3
               if FAIL END \v(return)
               assign \%r \v(return)
          } else {
               Mammal::\v(macro) \%1 \%2 \%3
               if FAIL END \v(return)
               assign \%r \v(return)
          }
          return \%r
     }
}

;**************************************************
;*   PUBLIC USAGE INTERFACE OF THE CLASS BEAR     *
;**************************************************
define Bear::favorite_food {
     echo Honey
}
define Bear::destroy {
     Mammal::\%1 destroy
     _define \%1
}

;**************************************************
;*   DEFINITION OF THE CLASS ENDANGERED           *
;**************************************************
define Endangered {
; \%1 Endangered name
; \%2 endangered category
     _assign Endangered::\%1.category \%2
     _define \%1 {
          if define \m(Endangered::\%1) {
               Endangered::\%1 \v(macro) {\%2} {\%3} {\%4}
          } else {
               return doesNotUnderstand
          }
     }
}

;****************************************************
;*   PUBLIC USAGE INTERFACE OF THE CLASS ENDANGERED *
;****************************************************
define Endangered::category {
     echo \m(Endangered::\%1.category)
}
define Endangered::destroy {
     _define Endangered::\%1.category
     _define \%1
}

;**************************************************
;*   DEFINITION OF THE CLASS PANDA                *
;**************************************************
define Panda {
; \%1 name of the new Panda
; \%2 age of the new Panda
; \%3 endangered category of the new Panda
     Bear Bear::\%1 \%2 black_and_white
     Endangered Endangered::\%1 \%3
     _assign Mammal::Mammal::Bear::\%1.kind \v(macro)
     _define \%1 {
          local \%r super \%i \&a[]
          if define \m(Panda::\%1) {
               Panda::\%1 \v(macro) \%2 \%3 \%4
               if FAIL END \v(return)
               assign \%r \v(return)
          } else {
               assign super Bear:Endangered
               for \%i 1 \fsplit(\m(super),&a,:) 1 {
                    \&a[\%i]::\v(macro) \%1 \%2 \%3
                    if FAIL END \v(return)
                    assign \%r \v(return)
                    if define \%r {
                         if NOT EQUAL \%r doesNotUnderstand return \%r
                    }
               }
          }
          return \%r
     }
}

;**************************************************
;*   PUBLIC USAGE INTERFACE OF THE CLASS PANDA    *
;**************************************************
define Panda::destroy {
     _define Bear::\%1
     _define Endangered::\%1
     _define \%1
}

;**************************************************
;    USAGE SAMPLES                                *
;**************************************************

; BEJING presented the Zoo of NEWYORK with a Panda
; named Teddy, 3 years old, endangered category 5,
; its default color is naturally black_and_white.

Panda Teddy 3 5

; What kind of animal is Teddy?
Teddy kind          ; => panda

; How old is Teddy?
Teddy age           ; => 3

; What endangered category is Teddy?
Teddy category      ; => 5

; What is Teddy's favorite food?
Teddy favorite_food ; => honey

; Yesterday somebody stole Teddy, the Zoo administration
; deletes him from the zoo habitant list:
Teddy destroy

END
