Overloading New() and calling 'upper' New()
Monkey Forums/Monkey Programming/Overloading New() and calling 'upper' New()
| ||
Hi! I'm semi-new to MonkeyX, and what I'm trying to do, is pretty simple: Class MyClass Field x:Float, y:Float, z:Float Method New() Self.x = 0.0 ' Defaults Self.y = 0.0 Self.z = 255.0 End Method New(x:Float, y:Float) New MyClass() ' This cannot be assigned to Self Self.x = x ' Only changes X and Y, Z comes from "upper" New() Self.y = y End End Function Main:Int() Local mc:= New MyClass(10, 20) Print mc.x ' Prints 10 Print mc.y ' Prints 20 Print mc.z ' Prints 0, not 255 End Any ideas how this is done properly? |
| ||
Method New(x:Float, y:Float) New MyClass() ' This cannot be assigned to Self Self.x = x ' Only changes X and Y, Z comes from "upper" New() Self.y = y EndThis will never work as you are creating a new instance of MyClass with the constructor New() inside the constructor New(x:Float, y:Float). So the instance created by New(x:Float, y:Float) can not see the instance created by New(), unless you make it visible. You could also be creating a memory leak doing it this way, unless the instance goes out of scope when New(x:Float, y:Float) is finished and is cleaned up by the Garbage Collector. The code below is pointless, as you still have to assign z with what ever was created in the local c. This adds additional over head by creating the c:MyClass instance. Method New(x:Float, y:Float) Local c:MyClass = New MyClass() Self.x = x Self.y = y Self.z = c.z EndIf you want to assign a default value at instance initialisation. Then write the constructor like this Method New(x:Float, y:Float, z:Float = 255.0) Self.x = x Self.y = y Self.z = z EndYou can still write the calling method as Local mc:= New MyClass(10,10)or is you want to assign another value to z Local mc:= New MyClass(10,10,128)Or you can have the Fields written as Field x:Float, y:Float, z:Float = 255.0and not bother with Self.z = 255.0 in the constructors at all. Edit: If I remember, when you created an instance all Fields are automatically assigned default values depending on object type e.g. Int = 0, class:MyClass = NULL |
| ||
I would do it something like this:Strict Class MyClass Field x:Float = 0, y:Float = 0, z:Float = 255 ' assign defaults Method New() Init(0, 0, 255) End Method New(x:Float, y:Float) Init(x, y, z) End Method Init:Void(x:Float, y:Float, z:Float) Self.x = x Self.y = y Self.z = z End End Function Main:Int() Local mc:= New MyClass(10, 20) Print mc.x Print mc.y Print mc.z Return True End In Java, you can call the other contructor with "this" - I'm actually surprised that we can't do something similar in Monkey. public class HelloWorld{ public static void main(String []args){ MyClass mc = new MyClass(10.0f,20.0f); System.out.println(mc.x); System.out.println(mc.y); System.out.println(mc.z); } } class MyClass{ float x; float y; float z; MyClass() { x = 0.0f; y = 0.0f; z = 255.0f; } MyClass(Float x,Float y) { this(); this.x = x; this.y = y; } } |
| ||
In Java, you can call the other constructor with "this" - I'm actually surprised that we can't do something similar in Monkey. Would be something nice to have. |
| ||
In Java, you can call the other contructor with "this" And that's exactly what I was going for. Guess I'll have to settle with the additional "Init()" method for now... :( EDIT: Although this could be done by extending the class, then calling Super() to get defaults, but it sounds kinda stupid, doesn't it? |
| ||
In therevils example why is the default New() method not being called inside a "new" object with initialized variables already (i.e. z:Float = 255) ? In other words, why do we need the Init() method in New() ? |
| ||
You are right, Tiresius, He probably just forgot he had set a default. |
| ||
Okay thanks I thought I was misunderstanding some quirk of Monkey. :-) |
| ||
Usually I just have a 'Construct' method where my other constructors are. And, in the case of more advanced hierarchies, I have every class call their super-class's implementation of 'New', and in the ultimate super-class's 'New' command, I have it call 'Construct'. From there, each implementation of 'Construct' uses the "call the super" method, just as 'New' did. The only difference is, 'Construct' provides default values for variables, or sets up variables that always need to be setup. And for anything based on the arguments passed to 'New', I set them up in that implementation, or I make a class-specific construction command which isn't called 'Construct'. This whole thing would be a bit more streamlined if Mark would just allow me to overload methods properly, or at the very least let me call the main 'New' command. I suppose there is setting defaults "in-line", but that still seems terrible to me (For fields at least). But then again, some languages are starting to go this route these days. |