9

Is there a way in Haxe to get the equivalent of Java's abstract methods and abstract classes?

What I want is

// An abstract class.  (Written in a Java/Haxe hybrid.)
abstract class Process<A> {
    public function then<B>( f : A -> Process<B> ) : Process<B> {
        var a : A = go() ;
        return f(a) ;
    }

    abstract public function go( ) : A ;
} 

// A concrete class.
class UnitP<A> extends Process<A> {
    var _a : A ;

    public function new( a : A ) {
       _a = a ; }

    public override function go() : A { return _a ; }
}

The closest I've been able to get is to define Process as an interface and to implement it with a conceptually abstract class ProcessA, which defines both methods; the implementation of go in ProcessA simply crashes. Then I can extend my conceptually concrete classes off ProcessA.

Theodore Norvell
  • 15,366
  • 6
  • 31
  • 45
  • 1
    Haxe's "abstract" is something completely different, so no, not out of the box. Your solution works, and maybe it's possible with macros (what isn't possible with macros?). – MSGhero May 21 '15 at 17:09
  • Well my solution only works to a limited extent. There is no compile time warning if I forget to override `go` in a concrete class or if I instantiate `ProcessA`. – Theodore Norvell May 21 '15 at 17:26

3 Answers3

8

As mentioned by MSGhero, Java-style abstracts are not natively supported by Haxe. It was requested by several people though, so Andy Li wrote a macro to provide Haxe users with a comparable functionality:

https://gist.github.com/andyli/5011520

Gama11
  • 31,714
  • 9
  • 78
  • 100
Malte Köhrer
  • 1,577
  • 10
  • 19
2

How I'd do something equivalent in Haxe

  • Set the constructor private to ensure no instance of the Abstract class is created.
  • Create an Interface with all methods that must be implemented
  • Create a class that inherits from the Abstract and implements the Interface.

    // An interface
    interface IProcess<A, B> {
        public function then( f : A -> AProcess<B> ) : AProcess<B>;
    
        public function go() : A;
    }
    
    // An abstract class.
    class AProcess<A, B> {
        private function new() {}
    
        public function then<B>( f : A -> AProcess<B> ) : AProcess<B> {
            var a : A = go() ;
            return f(a) ;
        }
    
        private function go() : A {};
    }
    
    // A concrete class.
    class UnitP extends AProcess<A, B> implements IProcess {
        var _a : A ;
    
        public function new( a : A ) {
           super();
            _a = a ;
        }
    
        public function go() : A { return _a ; }
    }
    
bubblebenj
  • 116
  • 2
  • 1
    That's pretty much what I had (and still have). Is the explicit call to "super()" needed in order to invoke the constructor of the super class? (In Java, the call to super() is implicit if the is no explicit call to "super" or "this".) – Theodore Norvell May 26 '15 at 15:13
1

Haxe 4.2 (2021) introduced abstract classes, with syntax very much like proposed in this question:

abstract class Process<A> {
    public function then<B>( f : A -> Process<B> ) : Process<B> {
        var a : A = go() ;
        return f(a) ;
    }

    abstract public function go( ) : A ;
} 

// A concrete class.
class UnitP<A> extends Process<A> {
    var _a : A ;

    public function new( a : A ) {
       _a = a ; }

    // (note: no `override`)
    public function go() : A { return _a ; }
}

And if you were to omit declaration of go(), you would receive

src/Test.hx:31: characters 6-11 : This class extends abstract class Process but doesn't > implement the following method
src/Test.hx:31: characters 6-11 : Implement it or make UnitP abstract as well
src/Test.hx:27: characters 29-31 : ... go()

YellowAfterlife
  • 2,967
  • 1
  • 16
  • 24