Object-Oriented Programming Using SOM and DSOM:Understanding the Basics:Inheritance

From EDM2
Jump to: navigation, search

Inheritance is the mechanism that allows you to create new classes from existing classes. The original class is called the parent class or the base class. The derived class is called a child class or a subclass. The inheritance model in SOM is summarized below and is illustrated with usage examples.

  1. A subclass inherits interfaces from its parent classes: attributes (which are equivalent to a get and a set method) and methods that are available in a parent class are also available in any class that is derived either directly or indirectly from it.
  2. A subclass inherits implementations from its parent classes. The implementations are the procedures that implement the methods and can be written in any supported programming language.
  3. A subclass can introduce its own attributes and methods.
  4. A subclass can override (redefine) the methods from their parent classes using the override modifier.
  5. A class can disallow a method from being overridden by subclasses by using the noouerride modifier.
  6. When you redefine (override) an inherited method, you cannot change the signature of the method.
  7. A class cannot inherit from multiple parents that provide different methods of the same name.
  8. A class can inherit from multiple parents that have a common ancestor. In this case, the class only inherits one copy of the same method or attribute. An ambiguity situation may arise when one of its parents overrides a method in the common ancestor class. SOM uses the left path precedence rule to resolve this kind of ambiguity. This topic is discussed in detail in Section 3.7.6 on page 38.

The override and nooverride Modifiers

Let's look at the following Animal IDL.

interface Animal : SOMObject
{
  attribute string name;
  void sleep();
  void habitat();

  #ifdef _SOMIDL_
  implementation
  {
  releaseorder : _get_name, _set_ name, sleep, habitat;
  somInit: override;                  // Override inherited method somlnit
  sleep: nooverrlde;
  };
  #end if
}

The Animal class overrides the method somInit from its parent class SOMObject. It specifies that the sleep method cannot be overridden by subclasses, since all animals must sleep.

How to Invoke a Parent's Method

A subclass invokes a method introduced in a parent class using the same notation, as if the method is introduced by the subclass. That is, a subclass can use the form:

somSelf-><method.Name> (args)

to invoke a parent's method where args are the arguments to the method. To access a parent's attribute, the subclass would substitute <methodName> with the _get and the _set methods for the attribute.

When you run the SOM compiler to generate the implementation template for the class, a stub procedure is generated for each inherited method. A default implementation is also provided for each inherited method. The default implementation invokes the parent's method.

SOM generates convenience macros in the implementation header file so that a subclass can invoke the parent's method that it is overridding. Typically, a subclass calls the parent's method and then adds additional functions to the method. The macro has the following syntax:

<className>_parent_<parentClassName>_<methodName>

The following shows the stub procedure that is generated for the somInit method.

SOM_Scope void SOMLINK somlnit(Animal *somSelf)
{
  AnimaiData *somThis = AnimaiGetData(somSelf);
  AnimaiMethodDebug("Animal", "somInit");
  Animal_parent_SOMObject_somInit(somSelf);
}

The Animal_parent_SOMObject_somlnit macro invokes the SOMObject implementation of somInit. If a class has multiple parents, the SOM compiler will generate a macro for each of them.

Trying to OVerride a Method that Has nooverride Modifier

If a subclass attempts to override a method that has a rwoverride modifier, the SOM compiler produces an error. Let's look at the following Cat IDL:

#include <animal.idl>
interface Cat : Animal
{
   void meow();

   #ifdef _ SOMIDL_
   implementation
   {
    releaseorder: meow;
    sleep: override;
   };
#end if
};

When you compile the Cat IDL, the compiler produces the following error:

> "cat.idl", line 15: error: "sleep", cannot override "nooverride" methods.

Overriding an Attribute

Let's modify the Cat IDL to fix the sleep problem. We also want to override the name attribute. The new error-free Cat IDL is shown below:

#include <animal.idl>

interface Cat : Animal
{
    void meow();

    #ifdef _SOMIDL_
    implementation
    {
         releaseorder: meow;
         _set_name: override;
         _get_name: override;
     };
    #endif
};

When you override an attribute, you are actually redefining the pair of accessor methods on the attribute. It is illegal IDL syntax to specify name: override. The compiler will produce an error because it assumes you are trying to re-define a method called name, which is not present in the base Animal class. (Recall how an attribute is short-hand for a _get and a _set method.)

Ambiguity with Multiple Inheritance

It is illega1 IDL to inherit from two interfaces with the same method name. Let's look at the following example. We add a new class Pet. The Pet IDL is shown below. It introduces two methods habitat and owner.

#include <Somobj.idl>
interface Pet : SOMObject
{
    void habitat();
    void owner();
    #ifdef _SOMIDL_
    implementation
    {
        releaseorder: habitat, owner;
    };
    #endif
};

We modified our Cat IDL so that it inherits from both Animal and Pet. The new Cat IDL is shown below:

#include <animal.idl>
#include <pet.idl>

interface Cat : Animal, Pet
{
 void meow();

 #ifdef _ SOMIDL_
 implementation
 {
           reieaseorder: meow;
 };
 #end if
};

When we compile the Cat IDL, the compiler produces the following error:

> "cat.idl", line 5: error: "habitat" ambiguous: introduced by "Animal" and "Pet".

Left Path Precedence Rule

If a class inherits from multiple parents that have a common ancestor, the class only inherits one copy of the same method. However, an ambiguous situation can arise when one of its parents overrides a method in the common ancestor class. Which implementation should this class inherit? Should it inherit the implementation from the common ancestor class or should it inherit the implementation from the class that overrides the method? Consider the inheritance diagram in Figure 3.3.

SOM-DSOM-Fig-3-3.png

Figure 3.3 Common parents in multiple inheritance

The LiuingThings class defines a method breath, implemented by procedure procl. The Animal and the Pet class are derived from the LiuingThings class. The Pet class overrides the implementation of the breath method withproc4. The class Cat is derived from both the Animal and the Pet class. Which implementation of the breath method does the Cat class inherit?

SOM resolves this ambiguity by using the left path precedence rule: the procedure that is used for the method is the one that is on the leftmost path. The ordering is determined by the position of the parent classes in the IDL specification. In our example, assuming that the IDL for the Cat class lists the parent Animal before Pet, Cat inherits the implementation of the breath method defined by the class LiuingThings instead of the class Pet.

A conceptual diagram that shows the method table for Cat is shown in Figure 3.4. A method table is a table of pointers to the procedures that implement the methods that an object supports. This table is built by the class of the object. The breath method in the Cat class is implemented using procl instead of proc4, since the Animal class is the left most ancestor of Cat, from which the method breath is inherited.

SOM-DSOM-Fig-3 4.png

Figure 3.4 Method table for cat