ET: General Properties

Here is an overview of the facilities supported by Eiffel:

  • Completely object-oriented approach. Eiffel is a full-fledged application of object technology, not a "hybrid" of O-O and traditional concepts.
  • External interfaces. Eiffel is a software composition tool and is easily interfaced with software written in such languages as C, C++, Java and C#.
  • Full lifecycle support. Eiffel is applicable throughout the development process, including analysis, design, implementation and maintenance.
  • Classes as the basic structuring tool. A class is the description of a set of run-time objects, specified through the applicable operations and abstract properties. An Eiffel system is made entirely of classes, serving as the only module mechanism.
  • Consistent type system. Every type is based on a class, including basic types such as integer, boolean, real, character, string, array.
  • Design by Contract. Every system component can be accompanied by a precise specification of its abstract properties, governing its internal operation and its interaction with other components.
  • Assertions. The method and notation support writing the logical properties of object states, to express the terms of the contracts. These properties, known as assertions, can be monitored at run-time for testing and quality assurance. They also serve as documentation mechanism. Assertions include preconditions, postconditions, class invariants, loop invariants, and also appear in "check" instructions.
  • Exception handling. You can set up your software to detect abnormal conditions, such as unexpected operating system signals and contract violations, correct them, and recover
  • Information hiding. Each class author decides, for each feature, whether it is available to all client classes, to specific clients only, or just for internal purposes.
  • Self-documentation. The notation is designed to enable environment tools to produce abstract views of classes and systems, textual or graphical, and suitable for reusers, maintainers and client authors.
  • Inheritance. You can define a class as extension or specialization of others.
  • Redefinition. An inherited feature (operation) can be given a different implementation or signature.
  • Explicit redefinition. Any feature redefinition must be explicitly stated.
  • Subcontracting. Redefinition rules require new assertions to be compatible with inherited ones.
  • Deferred features and classes. It is possible for a feature, and the enclosing class, to be specified -- including with assertions -- but not implemented. Deferred classes are also known as abstract classes.
  • Polymorphism. An entity (variable, argument etc.) can become attached to objects of many different types.
  • Dynamic binding. Calling a feature on an object always triggers the version of the feature specifically adapted to that object, even in the presence of polymorphism and redefinition.
  • Static typing. A compiler can check statically that all type combinations will be valid, so that no run-time situation will occur in which an attempt will be made to apply an inexistent feature to an object.
  • Object test ("type narrowing"). It is possible to check at run time whether the type of an object conforms to a certain expectation, for example if the object comes from a database or a network.
  • Multiple inheritance. A class can inherit from any number of others.
  • Feature renaming. To remove name clashes under multiple inheritance, or to give locally better names, a class can give a new name to an inherited feature.
  • Repeated inheritance: sharing and replication. If, as a result of multiple inheritance, a class inherits from another through two or more paths, the class author can specify, for each repeatedly inherited feature, that it yields either one feature (sharing) or two (replication).
  • No ambiguity under repeated inheritance. Conflicting redefinitions under repeated inheritance are resolved through a "selection" mechanism.
  • Unconstrained genericity. A class can be parameterized, or "generic", to describe containers of objects of an arbitrary type.
  • Constrained genericity. A generic class can be declared with a generic constraint, to indicate that the corresponding types must satisfy some properties, such as the presence of a particular operation.
  • Garbage collection. The dynamic model is designed so that memory reclamation, in a supporting environment, can be automatic rather than programmer-controlled.
  • No-leak modular structure. All software is built out of classes, with only two inter-class relations, client and inheritance.
  • Once routines. A feature can be declared s "once", so that it is executed only for its first call, subsequently returning always the same result (if required). This serves as a convenient initialization mechanism, and for shared objects.
  • Standardized library. The Kernel Library, providing essential abstractions, is standardized across implementations.
  • Other libraries. Eiffel development is largely based on high-quality libraries covering many common needs of software development, from general algorithms and data structures to networking and databases.

It is also useful, as in any design, to list some of what is not present in Eiffel. The approach is indeed based on a small number of coherent concepts so as to remain easy to master. Eiffel typically takes a few hours to a few days to learn, and users seldom need to return to the reference manual once they have understood the basic concepts. Part of this simplicity results from the explicit decision to exclude a number of possible facilities:

  • No global variables, which would break the modularity of systems and hamper extendibility, reusability and reliability.
  • No union types (or record type with variants), which force the explicit enumeration of all variants; in contrast, inheritance is an open mechanism which permits the addition of variants at any time without changing existing code.
  • No in-class overloading, which by assigning the same name to different features within a single context, causes confusions, errors, and conflicts with object-oriented mechanisms such as dynamic binding. (Dynamic binding itself is a powerful form of inter-class overloading, without any of these dangers.)
  • No goto instructions or similar control structures (break, exit, multiple-exit loops) which break the simplicity of the control flow and make it harder or impossible to reason about the software (in particular through loop invariants and variants).
  • No exceptions to the type rules. To be credible, a type system must not allow unchecked "casts" converting from a type to another. (Safe cast-like operations are available through object test.)
  • No side-effect expression operators (such as +=) confusing computation and modification.
  • No low-level pointers, no pointer arithmetic, a well-known source of bugs. (There is however a type POINTER, used for interfacing Eiffel with C and other languages.)