Design‎ > ‎

Classes and Interfaces

Based on experience with other languages, we make these basic choices:
  • Interfaces are important and first class citizens of the language.
  • Classes use a single inheritance mechanism.  Multiple inheritance is too complicated.
  • When specifying an Implementation this implicitly defines an interface for the implemented items.
  • A class can be built from smaller parts.  These parts can specify both implementation and interface.

Every class has an interface

Interfaces, as used by Java, turn out to be a very clear mechanism.  However,
it can sometimes lead to repeating the signature definition of a method
several times: In the interface and with each method that implements it.
We need to find ways to avoid that when it is not needed.  And still make sure
the compiler produces an error when you do something wrong.

In Zimbu every class implicitly defines an interface.  This means that when you define
a class, with all its methods and attributes, this results in both an implementation
and an interface definition.  The name of the interface is equal to the class name
with ".I" appended.  Thus the class Border defines the interface Border.I.

An explanation and supporting arguments are on the Reference Type page.


Subclassing

One of the basic mechanisms of modern programming languages is
inheritance: define a basic class and then derive subclasses from it.
We want to support this in Zimbu.

The devil is in the details.  We need to help the programmer to avoid
mistakes.  How this is done is discussed on the Abstract and Virtual page.


Composition of Interfaces and Implementations

Part of the implementation of a class is often the same as what is used in
other classes.  We don't want to write the same code twice, for obvious
reasons.  How do we share parts of one class with another class?
There are many mechanisms available.  Some of the most well known are:
  • Composition (adding an instance of an object as an attribute of the class)
    is simple, but requires a lot of glue code. And requires knowledge of the
    interface.
  • Use a separate class with static methods, like Collections in Java.  This
    works but separates the functionality and puts it in a distant location.
  • Multiple inheritance has been implemented by a few languages, it turns out
    to be very complex.  Let's not use it.
  • Mixins have been suggested as a replacement for multiple inheritance, but
    they are still complex.
  • Traits have recently become popular.  However, their use is rather limited,
    since they only define method implementations.
  • Stateful traits seem to be the best solution.
In Zimbu we use something that is similar to Mixin and Trait, but a little different.
We also support composition with some extra mechanisms to avoid bulky glue code.

This is discussed on the Class composition page.  This talks about the choice to
use the PIECE definition, with INCLUDE statements and statements to connect
and wrap methods.  Together this reduces duplication and defines a mechanism
for code reuse that is simple to understand, efficient and avoids mistakes.


More choices

There are many choices to be made.  A few more on the class details page.


Building blocks

The resulting building blocks are:

 CLASS a normal class
 defines outside interface
 defines no inside interface
 contains implementation
 can be instantiated to make objects
 can be subclassed
 FINAL CLASS
 a class that cannot be subclassed defines outside interface
 defines no inside interface
 contains implementation
 can be instantiated to make objects
 cannot be subclassed
 ABSTRACT CLASS
 a class lacking part of the implementation defines outside interface
 defines no inside interface
 contains part of the implementation
 cannot be instantiated
 can be subclassed
 PIECE a building block of a class
 defines outside interface
 defines inside interface
 contains implementation
 cannot be instantiated
 cannot be subclassed
 INTERFACE does not have any implementation
 defines outside interface
 defines no inside interface
 contains no implementation
 cannot be instantiated
 can be subclassed