Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement inner non-static interface

I would like to instantiate an an inner non-static interface from outside the wrapping class.

Is this possible?

Consider the following code:

shared class AOuterClass() {
Integer val = 3;
shared interface AInterface {
        shared Integer val => outer.val;
    }
}

void test() {
    AOuterClass o = AOuterClass();
    object impl satisfies ???.AInterface{}
}

I think object impl satisfies o.AInterface{} would be my reasonable intuition, but the compiler does not allow it.

like image 319
Matthias Sokolowski Avatar asked Jul 27 '17 18:07

Matthias Sokolowski


1 Answers

It is not possible in a case like your one.

The Ceylon specification says (section 4.5.4 Class Inheritance):

A subclass of a nested class must be a member of the type that declares the nested class or of a subtype of the type that declares the nested class. A class that satisfies a nested interface must be a member of the type that declares the nested interface or of a subtype of the type that declares the nested interface.

So you can only satisfy a nested interface inside the declaring class, or in a subclass thereof. Similar language is there for extending a nested interface by a new interface.

This does not directly mention object declarations, but those are merely a shortcut for class definitions, as elaborated a bit later, in Anonymous classes:

The following declaration:

shared my object red extends Color('FF0000') {
     string => "Red";
}

Is exactly equivalent to:

shared final class \Ired of red extends Color {
     shared new red extends Color('FF0000') {}
     string => "Red";
}

shared my \Ired red => \Ired.red;

Where \Ired is the type name assigned by the compiler.

So this also covers object declarations as your one.

What you might be able to do (I didn't test this):

AOuterClass.AInterface test(){
    object o extends AOuterClass() {
       shared object impl satisfies AInterface{}
    }
    return o.impl;
}

Of course, this doesn't work for an existing AOuterClass object, just for a newly created one. Seeing that this allows accessing a private value of an object, this seems to be a good thing.

like image 181
Paŭlo Ebermann Avatar answered Sep 28 '22 14:09

Paŭlo Ebermann