Implementing of INTERFACEs in Derived Classes

Top  Previous  Next

In versions of Clarion prior to 6.3, a derived child class cannot have the IMPLEMENTS attribute for the same INTERFACEs implemented by the parent class. When this rule is violated the compiler warns about a duplicate field label in the Child class, and if the user ignores the warning in effect he/she loses the derived child class implementations of the interface.

In the current release, if the duplicate label WARNING is ignored then calling the childs interface of the method actually executes the Parent’s implementation.

This version supports the re-implementing of INTERFACEs in derived classes. With the new implementation, if the child class has the IMPLEMENTS attribute for an interface already implemented above it in the hierarchy, the compiler builds a new interface VMT.

 

Example:

 

IFace    INTERFACE

M1         PROCEDURE()

M2         PROCEDURE()

        END

 

Base     CLASS,TYPE,IMPLEMENTS(IFace)

X         PROCEDURE()

        END

 

Child    CLASS(Base),TYPE,IMPLEMENTS(IFace)

XY        PROCEDURE()

        END

 

In Clarion 6.3 and greater, the Virtual Memory table (VMT) pointed to by Base.IFace contains pointers to functions Base.IFace.M1 and Base.IFace.M2 while the VMT pointed by Child.IFace contains pointers to functions Child.IFace.M1 and Child.IFace.M2.

 

More important, if a child class has the IMPLEMENTS attribute for an interface implemented above in it in the hierarchy, not all of the interface's methods have to be overridden.

 

In the example code above, the Child class may only re-implement the M2 method. If some of the interface's methods are not re-implemented in a child class, the compiler generates stub functions for them, which contain the proper jump instructions to the nearest implementation going up in the hierarchy. So in the above example, if the Child.IFace.M1 method is not implemented explicitly, the compiler will generate code for it which calls the implementation in the Parent class! This is a huge advantage and flexibility in Clarion 6.3.

 

The example code below shows a very simple program using these concepts.

 

 PROGRAM

 MAP

 END

 

IFace INTERFACE

MyIProc  PROCEDURE

MyIProc2 PROCEDURE

MyIProc3 PROCEDURE

     END

 

Base  CLASS,IMPLEMENTS(IFace)

cMyProc  PROCEDURE

     END

 

Child CLASS(Base),IMPLEMENTS(IFace) !Valid only in Clarion 6.3 and greater

bMyProc  PROCEDURE

     END

 

AnotherChild  CLASS(Base)

IChild         &IFace

             END

 

 CODE

 Base.cMyProc

 Child.bMyProc

 Child.cMyproc         !Calls Base.cMyProc

 Base.IFace.MyIProc

 Child.IFace.MyIProc   !comments:

!Prior to C 6.3, if the user ignores the "duplicate label warning" it really

!calls the parent’s base.iface.MyIProc method. In C6.3 and greater, it calls

!the child.iface.MyIProc implementation.

 

 Child.IFace.MyIProc2  !Calls Base.IFace.MyIProc2

 Child.IFace.MyIProc3  !Calls Base.IFace.MyIProc3

 

!procs/methods

Base.cMyProc       PROCEDURE

 CODE

 MESSAGE('Base.cMyProc')

 

Child.bMyProc       PROCEDURE

 CODE

 MESSAGE('Child.bMyProc')

 

! interface implements

Base.IFace.MyIProc       PROCEDURE

 CODE

 MESSAGE('Base.IFace.MyIProc')

 

Base.IFace.MyIProc2       PROCEDURE

 CODE

 MESSAGE('Base.IFace.MyIProc2')

 

Base.IFace.MyIProc3       PROCEDURE

 CODE

 MESSAGE('Base.IFace.MyIProc3')

 

Child.IFace.MyIProc       PROCEDURE

 CODE

 MESSAGE('Child.IFace.MyIProc')

 

An important note regarding the above example. Consider this CLASS definition:

 

Child CLASS(Base),IMPLEMENTS(IFace)

bMyProc  PROCEDURE

     END

 

The Child class actually only implements ONE method from the IFace interface, but the code calls all three interface methods.

 

See Also:

INTERFACE

IMPLEMENTS