Search code examples
autohotkey

AhkV1: Is possible to create a class with constructor overloads?


For example if I have a class that constructs a Timecode object, I would like to sometimes initialise a instance by just providing a value for a single parameter (frameCount) and other times provide more than one parameter such as frameCount and frameRate.

Here is what I tried:

obj := new timecode(2)          ;Default to using 12 frames per second
print(obj)                          ;prints ---> {"frameCount": 24, "framerate": 12}
obj := new timecode(2, 24)  ;Use the provided frame rate 
print(obj)                          ;prints ---> {"frameCount": 48, "framerate": 24}


class timecode
{
    __New(frames)
        {
            this.frameCount := frames * 12
            this.framerate := 12
        }
    __New(frames, framerate)
        {
            this.frameCount := frames * framerate
            this.framerate := framerate
        }
}

but the above just throws an error:

 ==> Duplicate declaration.
     Specifically: __New
AutoHotkey closed for the following exit code: 2

I know that V1 is as dead as latin, and V2 classes are much better now but until the library porting for V2 catches up, I will be on V1.

Any help would be greatly appreciated!


Solution

  • To my knowledge, there is no direct way to create a class with constructor overloads. A good indirect way that may work is the following:

    ; Define a struct to hold the properties of your "class"
    MyClass := {}
    
    ; Define a function to act as the constructor
    MyClass_New(name := "", age := 0) {
        ; Initialize a new instance of the class
        local obj := {}
        
        ; Set the properties based on the arguments passed to the constructor
        obj.name := name
        obj.age := age
        
        ; Return the instance
        return obj
    }
    
    ; Usage:
    obj1 := MyClass_New("John", 30)
    obj2 := MyClass_New("Jane")
    

    EDIT: I seemed to misunderstand your question. Here is how I would get around constructor overloading:

    class timecode
    {
        __New(frames, framerate := 12)
        {
            if (IsObject(framerate))
            {
                ; If framerate is provided as an object, assume it's the options object
                this.frameCount := frames * (framerate.framerate ? framerate.framerate : 12)
                this.framerate := framerate.framerate ? framerate.framerate : 12
            }
            else
            {
                ; If framerate is provided as a separate parameter
                this.frameCount := frames * framerate
                this.framerate := framerate
            }
        }
    }
    
    obj := new timecode(2)          ; Default to using 12 frames per second
    MsgBox % "Frame Count: " obj.frameCount ", Frame Rate: " obj.framerate
    
    options := { framerate: 24 }
    obj := new timecode(2, options) ; Use the provided frame rate 
    MsgBox % "Frame Count: " obj.frameCount ", Frame Rate: " obj.framerate