Anonymous class from Java to Oxygene?

How can i write this in Oxygene? Oxidizer say it isn’t supported.

 mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

When I did this in Oxygene I created an explicit ActionBarDrawerToggle subclass.

However. For things that are declared as interfaces (unlike ActionBarDrawerToggle) you can do something like this:

  vw.ViewTreeObserver.addOnGlobalLayoutListener(new interface ViewTreeObserver.OnGlobalLayoutListener(onGlobalLayout:= method begin
                                                                                                                          checkPickerSize();
                                                                                                                        end));

i believe this same syntax should work with a vase class, too, i.e. new class Foo(...). That said, no promise,i’m not 100% sire if this was just discussed or actually implemented yet, and i cannot check right now.

I know it’s almost 3 years later, but I’ve run into exactly this same scenario.

I cannot fathom the syntax to subclass and instantiate an anonymous class, as Java is doing in this case. The generalised case (in Java) is:

var foo = new ClassToBeSubclassed( ctorParam1, ctorParm2 )
{
    public void OverrideMethod1
    {
    }

   public void OverrideMethod2
    {
    }
 }

The equivalent (?) Oxygene does not compile:

 var foo := new class(ClassToBeSubclassed) ( ctorParm1, ctorParm2,

   OverideMethod1 = method(aParm: Bar)
   begin
   end,

   OverideMethod2 = method(aParm: Bar)
   begin
   end
);

I get a type mismatch compilation error on the ClassToBeSubclassed reference and unknown identifier errors on the names of the methods being overridden.

If I remove the parentheses from around the super class identifier then I get a “no accessible constructors” error followed by an “inline interface member expected” error and what appears to be a complete breakdown of compilation of the rest of the unit (a heap of spurious errors relating to the implementation of the class in whose method this code is placed).

With the parentheses there are no red-line indications of any problems in the source, only compilation errors. Without the parentheses the first ctor parameter is red-lined along with the second method override and an identifier within that method body. So I might expect compilation errors in the second case (superclass not parenthesised), but not the first.

Is this supported ? What’s the incantation if it is ? I’m hoping that the reason there was no follow up on this aged post was because the OP found a way to do it. :crossed-fingers:

If not, then I presume I cannot use an anonymous class in this case and have to declare a named class ?

Many thanks in advance.

i believe it’s new interface <BaseClass> (<.ctor params>) <methods> end;, but i’m not sure. Carlo will need to clarify this tomorrow.

new interface <BaseClass> (
  OverrideMethod1 := method begin end,
  OverrideMethod2 := method(aParm:  Bar) begin end,
)

ought to do it.

1 Like

Thanks Carlo but that doesn’t involve any ctor params and it seems to be these that cause the problem:

namespace SubClass;

  type
    FooA = public class
    protected
      method Bar; virtual; empty;
    end;


    FooB = public class
    protected
      method Bar; virtual; empty;
    public
      constructor(id: Integer);
      begin
        inherited();
      end;
    end;


    Program = class
    public
      class method Main(args: array of String): Int32;
      begin
        var foo1 := new interface FooA (Bar := method begin end );
//        var foo2 := new interface FooB (42, Bar := method begin end );
      end;
    end;

end.

As written, the above code is fine. But if you uncomment the foo2 := which passes a required param to the ctor in addition to the method overrides, then a host of spurious compilation errors arise. e.g. E152 No accessible constructors for type FooB (that’s just the first of many and is very obviously wrong).

fyi: Behaviour is identical with both Echoes and Cooper.

sounds like a bug then, but i’ll let Carlo confirm/log tomorrow.

Thanks, logged as bugs://77360

not a bug really, more like a missing feature. this has to be done as a proper class for now.

I thought that might be the case.

Just out of curiosity, I know this horse long since bolted but is there any particular reason that anonymous subclasses use the interface keyword rather than class ?

The way this might have worked…:

new class ( <declare/init properties> );  // The existing support for anon classes

new class <BaseClass> ( <ctor params>, <init properties/override methods> );  // Not currently supported

And then, for the trifecta, an anonymous subclass implementing one or more interfaces:

new class <BaseClass>, <Interface1>, <InterfaceEtc> ( <base class ctor params>, <init properties/override/implement methods> );

The first identifier following class must identify an extensible class (i.e. not final etc) followed by a comma separates list (optional) of any interfaces to be implemented.

The new interface incantation then completes a superfecta, providing convenience when implementing a ‘pure’ implementation of a single interface (derived from object rather than any other base class). i.e. syntactic shorthand

new interface <Interface1>, <InterfaceEtc> ( <methods> );

// Exactly equivalent to...
new class Object, <Interface1>, <InterfaceEtc> ( <methods> );

As I say, I know this horse has bolted, but just curious if there is a particular reason that I’m not grasping. I frequently get caught out by the need to use new interface for an anonymous _sub_class (w/o interfaces) vs new class for an anonymous class (also w/o interfaces).

If I understood the reason it might help me remember. :slight_smile:

Mostly historic. I’ll have to find a non conflicting syntax that doesn’t interfere with the old one.

It also just dawned on me that multiple interfaces are not currently supported on an anonymous class, but (I think) could be:

namespace MultiInterfaces;

  type
    SuperFoo = class
    public
      method Bar; virtual; empty;
    end;

    IFoo1 = interface
      method Bar;
    end;

    IFoo2 = interface
      method Bar;
    end;

    Program = class
    public
      class method Main(args: array of String): Int32;
      begin
        var o := new interface IFoo1, IFoo2 ( IFoo1.Bar := method begin end,
                                              IFoo2.Bar := method begin end );
      end;
    end;

The above obviously does not currently compile. The same technique for resolving interface methods could be applied when implementing an interface on a subclass with overridden methods:

        var o := new class SuperFoo, IFoo2
        (
          Bar := method begin end,       // Overrides SuperFoo.Bar
          IFoo2.Bar := method begin end  // Implements IFoo2.Bar
        );

Interface method implementations would require qualification to differentiate them from overrides of methods inherited from the base class.

The incantation could obviously still use new interface SuperClass, Interface1 if it had to. :slight_smile:

I may be missing something, but I wonder if a more capable new class syntax couldn’t simply co-exist alongside the existing `new interface’ syntax (which might then be officially deprecated, but still supported for backward compatibility) ?

AIUI the current support provides that when the compiler encounters:

new interface <TypeName> ( .. );

If TypeName identifies a class then it’s an anon subclass of TypeName.
If TypeName identifies an interface then it’s an anon subclass of Object that implements TypeName.

Extending a base class and implementing an interface on the anon subclass is not currently supported:

new interface <BaseClass>, <Interface> ();  // Not supported

Meanwhile when the compiler encounters:

new class ( .. );

Then this always implements an anon subclass of Object with some inline declared properties. This would be the special case for the new class syntax.

Otherwise, any new class <BaseClass> could not introduce any new properties and could only pass parameters to any inherited public ctors, followed by extension parameters to initialise public properties/members and/or implement or override inherited or declared interface methods).

The only slight wrinkle would be that these would be equivalent:

new interface <BaseClass> ();
new class <BaseClass> ();

The first being the current support for subclassing and overriding methods. AFAICS this could continue to be supported, but all the more sophisticated capabilities of anonymous subclassing, passing params to inherited ctors, implementing interface(s) etc would require the new class syntax.

In case you can’t tell, I quite enjoy thinking about language 'design" (if you can call off the cuff invention of syntax without consideration of existing compiler constraints and implementation details ‘design’ :slight_smile: ).

what I’d actually rather like to see is a syntax mimicking the existing class syntax, but then inline (like how Java does it). But it’s tricky as I have to make sure it won’t conflict (either way this won’t be in the next release), but something like (untested):

begin
  new class(BaseType) 
  public
    constructor(aName: String); begin end;
    method doIt; override; begin end;
  end('your name');
end;
1 Like

Hmmm, the first thing that jumps out is that Java places the ctor call first and then provides the implementation which doesn’t really map to Pascal very nicely due to the parenthesis around the baseclass which could look like a ctor call. Java’s use of {} here makes this possible. And I don’t think you can introduce new constructors on the anonymous class either, so it’s not a full class declaration and I’m not sure why you would want/need to. Also I’m not sure of the benefit of visibility specifiers or introducing new member fields. It all seems a bit … noisy.

The second thing that strikes me about this is that by making it more similar to a class declaration confuses the fact that it isn’t a class declaration, but rather an instantiation of an object under very specialised circumstances. If that makes sense ?

i.e. given…

var foo := new class(BaseType)
   public
       method doIt; begin end;
   end;

Which seems to give the impression that I might then reasonably expect to be able to do something like:

 var fooInstance := new foo;  // I just made foo a new class type, didn't ?

Personally I like the new class / new interface syntax, apart from the slight, seeming inconsistencies previously mentioned.

I don’t like that they essentially have anonymous methods hanging in there (But as I said the syntax isn’t final ofc), I’m not wholely opposed to something more like java. The syntax as always is the trickiest part :slight_smile:

Again I’ll “hmmm” :slight_smile: … as I noted in my recent blog posts about anon classes, Oxygene’s approach has the merit of being (mostly) consistent in this area. That is, overriding/implementing methods, declaring and initialising properties in a POPO and ctor extensions … they all follow the same pattern.

Adding entirely new members is however a complication:

type
  Foo = class
  public
     MemberC: Integer;
     Member1: Integer;
     constructor(memberCValue: Integer); begin inherited(); MemberC := memberCValue; end;
     method sum: Integer; virtual; begin result := MemberC + Member1; end;
  end;

// and then later ...

var f := new class Foo (
  42,             // ctor param
  Member1 := 12,  // ctor extension initialises inherited Member1
  Member2 := 24;  // ctor extension introduces new member on anon class
                  //  - or maybe I just mistyped the name of an intended 
                  //    existing member ?

  preSum := method  // ctor extension introduces new method (or again, maybe I made a typo ?)
  begin
     // Dunno, just an example of an introduced method
  end,

  sum := method: Integer   // ctor extension overrides the sum method
  begin
    preSum;  // Calling an introduced method
             // (if this wasn't here then preSum almost certainly was a typo)
    result := inherited + Member2;
  end
);

I wonder if the new keyword could not be employed here to distinguish between inherited members/methods and additional ones being introduced on the anon class ? Something perhaps like:

new class Foo (
  42,             // ctor param
  Member1 := 12,  // ctor extension initialises inherited Member1
  new Member2 := 24;  // ctor extension introduces new member on anon class

  preSum := new method  // ctor extension introduces new method
  begin
     // Dunno, just an example of an introduced method
  end,

  sum := method: Integer   // ctor extension overrides the sum method
  begin
    preSum;
    result := inherited + Member2;
  end
);

new might legitimately appear as the initial token in a ctor parameter to construct an object to be passed. But one all ctor params have been satisfied an initial new token (LHS) would signify the introduction of a member.

If the member (LHS) in a ctor extension does not identify an inherited member then it can only be a method being introduced and so the initialisation (RHS) is required to commence with new method (and illegal if it does not). Equally new method would be illegal if a member or method with that name does exist in the base type.

If interface resolution prefixes are in play ( IFoo.Bar := method ... ) then obviously it would not be legal to introduced new interface methods:

(
  ..
  IFoo.Bar2 := new method  // ERR: Cannot introduce new interface methods
  ..
);

new class () remains intact and preserved as a special case for POPO’s and so the new decoration on the members in that case is not required (since all members are/must be newly introduced). It might be redundantly supported for consistency, just isn’t required in that specific case.

It would presumably be easier (and I think cleaner) if the order in which these ctor extensions are introduced is enforced. ctor params first (they have to be) then member initialisation/introduction and finally any method overrides/implementation.

At the end of the day, the use case for this stuff is when your needs are (relatively) trivial and offer a convenience over a full, formally named class which is not otherwise warranted. But for more complex needs that formally named class alternative is of course still there.

I think that’s why the idea of a “full” inline class syntax doesn’t appeal (to me). It doesn’t offer the same streamlined convenience. I might as well just use a formal class and keep all the class decl boilerplate that it entails out of my code.

bugs://E19243 was closed as fixed.