Inheritance

In Uniface, inheritance is a mechanism in which definitions in one development object are applied to other objects that re-use the definition. This makes it possible to define common behavior in one place instead of everywhere that it is used, making it much easier to maintain the application.

For example, modeled entities are intended for re-use in components. Every component that uses a modeled entity initially inherits the definitions for that entity. If you make a change in a property or script module in the modeled entity, it is automatically applied to the inherited definition in the component during compilation.

Inherited properties and script modules can be overridden to suit a specific context. For example, if you change the widget type of a field, or define a trigger that behaves differently from the same trigger in the modeled entity, the locally defined property or trigger is used, not the inherited version.

Inheritance is central to the Uniface development paradigm:

  • Subtype entities inherit from supertype entities and from parent subtype entities.
  • Derived component entities inherit entity, field, and field property definitions from modeled entities and fields.
  • Derived components inherit component definitions from modeled components.
  • Entities, components, and application shells can inherit IncludeScript modules that are defined in IncludeScript libraries.

    Note:  Strictly speaking, IncludeScript is inserted locally. However, it is possible to insert an IncludeScript module and also define a module with the same name. One of these declarations will override the other, depending on where it is located.

Inheritance for IncludeScript and Modeled Entities

Inheritance

Overlay Inheritance

For ProcScript modules and compile-time constants (#define declarations), overlay inheritance is applied, which means that if a locally-defined module or declaration has the same name as an inherited declaration, or is encountered at a lower point in a component structure hierarchy, it takes precedence.

Thus, if you define an operation in a component entity, this will be added to the operations that may be inherited from the modeled entity. If it has the same name as an operation in the modeled entity, the locally defined operation will override the inherited operation.

ProcScript modules can be defined in many places—in modeled entities and fields, in IncludeScript, and locally in components, application shells, and Global ProcScript.

When a component or application shell is compiled, Uniface concatenates:

  • All inherited and locally-defined script modules. If a duplicate declaration is found, the last one encountered is used in the compiled component. (Modules defined in the component override those defined in modeled entities.)
  • All constants declared in the component and its subobjects.

    Inheritance of constants in a component is from Component to Entity to Field, but never from Entity to Entity (even from an outer entity to an inner entity) and never from Field to Field.

    If you have defined the same constant for an entity and several of its fields, the field-level constants override the entity-level constant.

  • All ProcScript entry modules. These are treated as if they are all defined at the component level, although they can be defined in any code container of any object.

Consequently, the compiled ProcScript may not always be what was expected. After compilation, it is possible to view the list of compiled modules for each object and to navigate to object and code container where it is declared, even if it is inherited.

For more information, see Compiled Module Information.

Related Topics