Interfaces_(re)

Fri, 30 May 1997 15:41:35 +0200 (MET DST)


According to Frank Heckenbach who cites "Java in a Nutshell":
> [...]
> While an 'abstract' class may define some 'abstract' methods and some non-
> 'abstract' methods, all the methods defined within an interface are
> implicitly 'abstract'. [The 'abstract' keyword can, but doesn't have to, be
> omitted.] [Note: In Java, all methods are what we call virtual.]
> [...]
> 
> So what can we do with an interface? Just as a class 'extends' [is derived
> from] its superclass, it also optionally 'implements' an interface.
> 'implements' s a Java keyword that can appear in a class declaration
> following the 'extends' clause. 'implements' should be followed by the name
> of the interface that the class implements. In order to implement an
> interface, a class must first delcare the interface in an 'implements'
> clause, and then it must provide an implementation (i.e. body) for all of
> the 'abstract' methods of the interface.
>
> [...]

As I understand this, the Interface mechanism is MI with the following
requirements:

  * Each object type has one "primary ancestor"; possible other ancestors
    are "secondary".

  * Definition:  An object type which does not have data fields, but only
    abstract (virtual) methods qualifies as an "interface".

  * The primary ancestor of an object may be any object; secondary
    ancestors must be interfaces.

This implies:

  * MI among interfaces works without restrictions.

  * Instances of interfaces are useless.

  * You cannot inherit data fields and function bodies via MI.

  * MI does no more cause all those catastrophies as it would be the case
    with unrestricted MI among "real" objects.

Making these rule obligatory, it would be save to introduce MI into GPC,
thus introducing interfaces without needing another keyword.  (Just an
idea.)  However since Delphi seems to have interfaces, we should use their
syntax rather than inventing another one.  (Just another idea.)

(* Hmm ... the above rules for "careful use of MI" could be useful for *)
(* C++ programmers ... perhaps we should tell them?                   :*)

> Concerning a possible implementation in gpc:
> 
> AFAICS, the only thing that really makes problems are variables (or
> parameters) of interface types.

What's the problem?  An instance of an interface would be an empty object,
containing nothing besides the VMT pointer.

> First of all, since interfaces can't be instantiated, such variables or
> parameters must be pointers (or var parameters). In Java, this is implied,
> since *all* object variables are pointers.

Do you mean:  If an object implements an interface (in Java sense) it must
always be accessed through a pointer?  If so, why?

> But such a pointer must point to the actual object and to the methods
> declared in the interface. Since different object types can implement the
> same interface, those methods will not always be at the same VMT offset.
> However, it is possible to guarantee that all methods of one interface
> are at consecutive VMT offsets (in the order they're declared in the
> interface). (*, see below)
> 
> So one needs the VMT offset of the interface's first method.
> 
> I can see (at least) two solutions:
> 
> - A "pointer" to an interface variable consists of two parts: the actual
>   pointer to the variable, and the VMT offset of the first method (or,
>   alternatively, directly the adress of the first method in the VMT).
> 
>   Disadvantage: The pointer gets twice as big. The difference must be
>   considered when assigning it to another pointer (this could be an untyped
>   pointer or a pointer of one of the "parent" interfaces - in the latter
>   case the VMT offset has to be adjusted).

I'm afraid we can forget about this for that reason.

> - The VMT must contain information about all interfaces that are implemented
>   together with the addresses of their methods. However, since different
>   object types can implement different interfaces, and one type can
>   implement more than one interface, I can't think of a method that doesn't
>   involve some kind of searching (searching the wanted interface out of
>   possibly many interfaces).

That's the problem why I initially asked about MI.

Does anybody know how C++ solves that problem?  Or Java?  Or Delphi?

> So this is basically a speed vs. size tradeoff. For most applications,
> I think, speed is to be favoured (and 32 bit programming favours speed,
> anyway), so I'd prefer the first solution. I can't see a solution without
> a need of either searching or additional data *per variable* (whereas
> additional data per VMT wouldn't matter so much).

I agree.  Calling virtual methods works quite fast as it is implemented
now.  If having interfaces (or MI in general) would slow this down, I would
vote against it.

But this is quite an interesting problem - not a technical one, how to
implement this-or-that without interfering with that-or-this syntax from
another dialect.  Here we have a problem where it is not even clear that
a fast (i.e. O(1)) solution exists.  :-(-:

Yours,

    Peter

  Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
 maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]


Peter Gerwinski (peter@agnes.dida.physik.uni-essen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es