Why is this possible?
BlitzMax Forums/BlitzMax Programming/Why is this possible?
| ||
Why is this possible?Type MyTypeA Field MyField:MyTypeB = New TypeB End Type Private Type MyTypeB Method Draw:int() End Method End Type Public Local MyInstance:TypeA = New TypeA MyInstance.MyField.Draw() Why it is possible to access private types functionality by a public field? Shouldn't this produce compiler errors? If it is legit, then you can use a private type instanced in a field of a public type to store and get all private fields, methods, globals and funcs in a class!! Something like: Type MyClass Field _Private:MyClassPrivate = New MyClassPrivate Method MyMethod1:int() 'Use a private field: Return _Private.PrivateField1 End Method Method MyMethod2(K:int, J:Int) 'Call internally a private method: Local X:int = _private.MyMethod1(self, k) 'Store the result in a private field: _private.PrivateField1 = x End Method End Type Private Type MyClassPrivate Field PrivateField1:int, PrivateField2 Method PrivateMethod1:int(BaseClass:MyClass, OtherParams) End Method end Type Is this 'legal' ? |
| ||
Why is this possible: Private only means that stuff within that area can not accessed by anything outside this BMX it does not protect it from any other stuff. It is only for functionality hidding. Its similar to Javas Protected that only allows access within the same package. |
| ||
Yes but it is allowed in modules! It compiles but it doesn't find methods or fields. That's awesome. code for MyFile.bmx: SuperStrict Import blide.test1 Local i:MyTypeA = New MyTypeA i.MyField.Draw() code for module blide.test1 (blitzmax/mod/blide.mod/test1.mod/test1.bmx) Type MyTypeA Field MyField:MyTypeB = New MyTypeB End Type Private Type MyTypeB Method Draw:int() End Method End Type Public Local MyInstance:MyTypeA = New MyTypeA MyInstance.MyField.Draw() Isn't this a very interesting way to have a sort of private fields and methods on modules? |
| ||
No it is not. Extension is broken which makes them quite pointless / totally defeats the point of OO. There are potentially simpler ways to get it out of the "known variable space". |
| ||
No, extension is not broken, that's the amazing point! I think the example i was providing is not really showing what I mean: Code for module blide.test1 (blitzmax/mod/blide.mod/test1.mod/test1.bmx) SuperStrict Import brl.max2d Type LineConcat Field _private:TLConcatPrivate = New TLConcatPrivate Method DrawLine(x:Int, y:Int) _private.DrawLine(Self, x, y) End Method Method SetPos(x:Int, y:Int) _private.X = x _private.Y = y End Method End Type Private Type TLConcatPrivate Field X:Int Field Y:Int Method DrawLine(LC:LineConcat, x:Int, y:Int) brl.max2d.DrawLine(x, y, Self.X, Self.Y) Self.X = x Self.Y = y End Method End Type Public And then, the sample code for MyFile.bmx: SuperStrict Import blide.test1 Graphics(800, 600) Cls Flip Local P:LineConcat = New LineConcat p.SetPos(Rand(0, 800), Rand(0, 600)) While Not KeyHit(KEY_ESCAPE) p.DrawLine(Rand(0, 800), Rand(0, 600)) SetColor 0, 0, 0 DrawText("Using base class. (PRESS ESC)", 1, 1) SetColor 255, 255, 255 DrawText("Using base class. (PRESS ESC)", 0, 0) Flip() Wend Cls Type LineConcatExtended Extends LineConcat Method DrawLine(x:Int, y:Int) SetColor(Rnd(0, 255), Rnd(0, 255), Rnd(0, 255)) Local F:Float = GetLineWidth() SetLineWidth (7) Super.DrawLine(x, y) SetLineWidth(F) End Method End Type Local p2:LineConcatExtended = New LineConcatExtended While Not KeyHit(KEY_ESCAPE) p2.DrawLine(Rand(0, 800), Rand(0, 600)) SetColor 0, 0, 0 DrawText("Using extended class. (PRESS ESC)", 1, 1) SetColor 255, 255, 255 DrawText("Using extended class. (PRESS ESC)", 0, 0) Flip() Wend In fact, in this example, the class LineConcat has a 'friend private' fields X and Y. Those fields are not accesible outside the module becouse they're based on a private type, but the class is still extensible outside the module. they are not real 'private' obviously, but they work a lot like visual basic .net 'friend' atributes, so they are only accesible inside the module. Obviously extending the class outside the module won't give you access to this sort of private fields and you will still have to call super.whatever to let the base class use them internally, but isn't this how friend fields are suposed to work? Am I missing something? I know it is not elegant, and maybe a litle bit heretic, but taking in consideration we don't have public and private at field or method level... Let me know what you think, please. |
| ||
OK that works. But you again assume that users accept the _ as private classifier. If they don't do, it totally bombs out the whole thing. It is by worlds simpler to just remove classes, definitions and functions from the .i files of the modules. There are only a few requirements that need to be met in your code ordering and it will work. Actually I do not understand why BM does not support it out of the box. |
| ||
Dreamora: Yes, modifying interfaces can solve the issue. But the interesting thing here is:If they don't do, it totally bombs out the whole thing. No it doesn't. If you try to use anything of the _private field, the compiler will tell you 'can't find field X' or whatever. So it is not possible to modify the contents of this field from the bmx file using the module. |