You get a bonus - 1 coin for daily activity. Now you have 1 coin

Programs with holes - 14. Inheritance in OOP: Kinds of

Lecture



Это окончание невероятной информации про наследование в ооп.

...

number of examples in later lectures will be based on this technique, which plays an important role in applying OO methods to the construction of reusable software. It is especially useful when building libraries for specific application domains and is actually used in many contexts. A typical example, described in [M 1994a], is the development of the Lex and Parse libraries, intended for language analysis. In particular, Parse defines a general parsing scheme, which will process any text (a data format for a programming language, and so on) whose structure conforms to some grammar. High-level behavior classes contain a small number of deferred features, such as post_action, describing the semantic actions that must be executed after parsing a given construct. To define its own semantic processing, the user need only implement these features.

Such a scheme is widespread. In particular, business applications often follow standard patterns - process the invoices received during the day, perform the corresponding checks on payment requests, enter new customers, and so on - the individual components of which may vary.

In such cases, one can provide a set of behavior classes with a mixture of effective features, describing the known part, and deferred features, specifying the variable elements. As a rule, the effective features will call the deferred ones in their bodies. With this approach, descendants can create implementations that satisfy their own needs.

Not every variable element should be deferred. If a default implementation is available, it should be included as an effective feature, which can be redefined at the descendant level if necessary. This will simplify the development of descendants, since they will only need to implement new versions of those features that differ from the default implementations. Of course, this technique should only be applied when a suitable default implementation exists; otherwise the corresponding feature should be declared deferred (as, for example, display in class FIGURE).

This technique is part of a more general approach that can be dubbed "Don't call us, we'll call you": it is not the application system that calls reusable primitives, but a general-purpose scheme that lets application developers place their own variants at strategic points.

This idea is not entirely new. The venerable old IBM IMS database management system already used something of this kind. The control structure of graphical systems (such as the X system for Unix) includes an "event loop", in which specific functions supplied by application developers are called on each iteration. This approach is known as the callback scheme (callback scheme).

What the OO method offers, through behavior classes, is systematic, safety-providing support for this development technique. This support includes classes, inheritance, type checking, deferred classes and features, as well as assertions, which let the developer state right away the conditions that the variable elements must always satisfy.

Programs with holes

The techniques just discussed are the central contribution of the OO approach to reuse: they do not offer components frozen forever (as can be found in subroutine libraries), but flexible solutions that provide basic schemes and can be adapted to the needs of many different applications.

One of the central themes in the discussion of reuse was the need to combine this goal with adaptability, in order to avoid the dilemma: reuse or redo. The scheme just described corresponds exactly to this, and can be given the name "programs with holes". Unlike subroutine libraries, in which everything except the values of actual arguments is rigidly fixed, programs with holes, using classes modeled after SEQUENTIAL_TABLE, leave room for parts created by the user.

These observations help us understand the "Lego block" image often used when discussing reuse. In a Lego set, the components are fixed, and the child's imagination is directed toward assembling them into an interesting structure. The same approach is characteristic of programming, whose roots lie in traditional subroutine libraries. Often, what software development requires is exactly the opposite: keeping the structure but replacing the components. In fact, these components may not yet exist at all; "stubs" (deferred features) are placed in their spots, in place of which effective variants must later be inserted.

By analogy with children's toys, one can go back to childhood and picture a game board with holes of various shapes, into which the child must insert the matching pieces. He must understand that the square block fits the square hole, and the round block fits the round hole.

One can also picture a partially deferred behavior class (or a set of such classes, called a "library") as a device with several electrical sockets - the deferred classes - into which the application developer will plug in compatible devices. This metaphor can be extended: for a device, safety precautions matter - assertions expressing the requirements on admissible pluggable devices, for example, the socket's specification determines the admissible voltage, current, and other electrical parameters.

The role of deferred classes in analysis and high-level design

Deferred classes also play a key role in applying the OO method not only at the implementation level, but also at the earliest and highest levels of system construction - analysis and high-level design. The goal is to produce the specification of the system and its architecture; a design also requires an abstract description of each module without the details of its implementation.

The recommendation usually given in this case is to use separate notations: some "method" of analysis (behind this term there often lies simply some graphical notation) and some PDL (in many cases also graphical, a program design language). But this approach has many drawbacks:

[x]. The gap between successive steps of the development process poses a serious threat to software quality. The need to translate from one formalism to another can lead to errors and endangers the integrity of the system. OO technology, by contrast, offers the prospect of a seamless development process.

[x]. A multi-tier approach is especially damaging for the stages of maintenance and system evolution. It is extremely difficult to guarantee the consistency of the design and the implementation at these stages.

[x]. Finally, most existing approaches to analysis and design offer no support for the formal specification of the functional properties of modules, independent of their implementation, for example in the form of assertions.

This last remark leads to the paradox of levels: a precise notation, such as the language used in this book, is sometimes dismissed as "low-level" or "implementation-oriented", because it outwardly looks like a programming language. In fact, however, thanks to assertions and such an abstraction mechanism as deferred classes, its level is substantially higher than that of most existing approaches to analysis and design. Many people need time to realize this, since they were previously taught that a high level of abstraction means vagueness, and that abstraction must always be imprecise.

Using deferred classes for analysis and design lets us be abstract and precise at the same time, and lets us apply the same language throughout the entire development process. This removes the conceptual gaps; the transition from a high-level module description to implementations can take place smoothly within a single formalism. Even the unimplemented operations of the modules being designed, represented by deferred procedures, can be characterized quite precisely by means of preconditions, postconditions, and invariants.

The notation, which by this point has been developed almost to completion, covers the stages of analysis and design as well as implementation. The same concepts and constructs are applied at every stage; only the levels of abstraction and detail differ.

Discussion

This lecture has introduced the basic concepts connected with inheritance. Let us now assess the merits of some of the conventions introduced. Further comments on the inheritance mechanism (in particular, on multiple inheritance) will appear in the next lecture.

See also

  • [[b9242]]
  • [[b7920]]
  • [[b3308]]
  • [[b4844]]
  • [[b5314]]
  • [[b4873]]
  • [[b9945]]

Продолжение:


Часть 1 14. Inheritance in OOP: Kinds of Inheritance
Часть 2 Redefinition and Assertions - 14. Inheritance in OOP: Kinds of
Часть 3 Programs with holes - 14. Inheritance in OOP: Kinds of

See also

created: 2020-07-15
updated: 2026-03-10
605



Was this answer useful?
Choose a quick rating so we can improve the next answer for you.
How satisfied are you?


Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Object oriented programming"

Terms: Object oriented programming