Inheritance provides a powerful means to organize a collection of objects. It may be used either to provide a conceptual model of the relations between the various objects that play a role in the system, as a mechanism to factorize code (as in the example showing how to factor out search control) or as a method of a stepwise refinement of object specifications. C.f.  [Tom87]. \nop{ As in the example showing how to factor out control, inheritance allows the common part of objects to be shared by isolating it in an object from which the shared code may be inherited. Such a mechanism is useful in particular for representing knowledge. }

Static inheritance

Inheritance may occur in a number of guises. Most simply, inheritance may be viewed as code-sharing. For the inheriting object, extra code must be specified such that the object in some sense specializes the inherited object. In a typed setting we would be tempted to speak of the inheriting object as belonging to a subtype of the type of the inherited object. However, in  [Am87a] it is adequately observed that subtyping is a far more abstract notion, that encompasses inheritance by code-sharing.

Dynamic inheritance

A rather different form of inheritance, found for instance in Actor languages  [Ag86], is achieved by delegating messages to the inherited objects, whenever the inheriting object does not provide any specific functionality for dealing with a method call. In contrast to code-sharing, inheritance by delegation is dynamic. See also  [US87]. Inheritance in DLP is static. Objects in DLP may inherit non-logical variables from other objects as well as clauses, by code sharing. With respect to the clauses of an object, inheritance in DLP must be regarded as a mechanism to extend a logical theory. Semantically, extending a theory results in a more precisely defined model. Operationally, it allows to derive more goals -- namely all the statements made true by the combined set of clauses. In this section we will give a more precise description of the inheritance mechanism offered by DLP. We will discuss multiple inheritance, what to do with name clashes, and we will explain the difference between overriding already defined clauses and adding clauses to allow (more) backtracking. As an example of the use of inheritance to specialize a given object, a semaphore will be characterized as a special kind of counter, extending the functionality of a counter with the behavioral characteristics of a semaphore. Next, an example will be given illustrating how to deal with self-reference when delegating messages to other objects. Finally, we will give an example to illustrate how inheritance may be used to add knowledge to an existing object by extending the definition of a predicate.