Inheritance

Gamma: Version 4.0
Prev | Chapter 8. Object Oriented Programming | Next

# 8.3. Inheritance

Let us consider the following example where a new class is created:

        class Book Catalog
        {
            size =  0;
        }

The `Book` class is called a derived class and the `Catalog` class is called a base, or parent class for the `Book` class. In addition to having its own attributes, methods, and class variables, a derived class inherits all these things from the base class as well. For example, the `Book` class inherits the `data` attribute from the `Catalog` class:

        (defclass Book Catalog [][data (size . 0)])

The relation between the base classes and the derived classes can be described as an "is-a" relation: a derived class "is-a" base class, with its own additional features. Due to inheritance, an instance of a derived class in Gamma can call any method of the base class just like it was an instance of the base class itself:

        Gamma> math = new(Book);
        {Book (data) (size . 0)}
        Gamma> math.Lookup("Calculus");
        nil

In this case it returns `nil` because no entry "Calculus" was added to the list of data. Now we can create an `Add` method for the `Book` class. This method adds an author and a publisher to the association list of data. If the `Add` operation is successful, the size of the list is incremented by 1. This Add method internally calls the `Add` method of the base `Catalog` class using the `call` function. We say that the derived class inherits implementation from the base class. If we were to change the way the `Add` method is implemented in the base class, the implementation would propagate to the derived class.

        method Book.Add (title, author, publisher)
        {
            local pair = list(author, publisher);
            local result = call(self, Catalog, Add, title, pair);

            if (result)
                {
                    .size+= 1;
                }
        }

The method `Add` can be evaluated as follows:

        Gamma> math.Add ("Calculus", "Thompson", "Wiley");
        1

It returns the size of the math catalog as the result of the last evaluated expression within the method. Now if we would like to search for the entry "Calculus", the method `Lookup` is evaluated as follows:

        Gamma>  math.Lookup ("Calculus");
        (Calculus (Thompson Wiley))

Classes can be related by "is-a" relations, since one class is a derived class of the other. There can also be "has-a" relations between classes. Let us consider the following example:

        class Figure
        {
            color;
            height;
            width;
        }

        class Book_1
        {
            size;
            figure = new(Figure);
        }

Class Book_1 "has" an instance of class Figure as an attribute. In other words, class Book_1 contains one instance of the class Figure. Let us consider the connections between the methods of the two classes with the "has-a" relations. Suppose the following methods are defined:

        method Figure.Show()
        {
        ...

        }

        method Book_1.Show()
        {
            .figure.Show();
        }

The method `Show` of the `Book_1` class internally calls the method `Show` of the `Figure` ("contained") class. We say that the `Book_1` class delegates its method to the `Figure` class. Thus, the effect of the delegation is implementation inheritance. It's true that to inherit implementation, the `Figure` class could be simply derived from the `Book_1` class and the "is-a" relations would be in effect. But then it would be impossible for an instance of the `Book_1` class to have several instances of the Figure class.

Note that in the definition of the `Book_1` class, the `Figure` class is instantiated, which makes the attribute `figure` an instance of the class `Figure`. Thus, if an instance of the `Book_1` class is created it can evaluate its `Show` method right away:

        ...
        mystery = new(Book_1);
        mystery.Show();
        ...

However, if an instance of `figure` is not actually created in a `Book` class definition,

        class Book_2
        {
            size;
            figure;
        }
        method Book_2.Show()
        {
            .figure.Show();
        }

then it has to be instantiated for each new instance of `Book_2` before any "delegation" will occur:

        ...
        mystery = new(Book_2);
        mystery.figure = new(Figure);
        mystery.Show();
        ...

Prev | Home | Next
Methods | Up | Instance Variables

Copyright 1995-2002 by Cogent Real-Time Systems, Inc.