OOP implemantation in BMax vs Java

BlitzMax Forums/BlitzMax Beginners Area/OOP implemantation in BMax vs Java

Barbapapa(Posted 2006) [#1]
Hi there, I have a neat book about OOP in Java, it's called Head First Java. As soon as I have learned that making a game with Java would need several years and much experience I got BMax. Now, of course, there are several differences in the way OOP is implemented. But I haven't yet found a list with all differences clearly stated.

What I have found it is that

- Interfaces are missing
- Method overloading is missing
- Multiple Inheritance is not allowed same as in Java

What else is there to know? I read some tutorials about OOP in BMax but they show a part of what goes and not was doesn't work.

So anybody cares about filling in the knowledge gap, make some sort of OOP in BMax vs Java or Ruby... reference
I could wrap it all up in a nice pdf or chm or html.

Oh and have a nice start in the new year :)


FlameDuck(Posted 2006) [#2]
- Multiple Inheritance is not allowed same as in Java
Multiple Inheritance is not allowed in Java either (Only interfaces).

Here's a list off the top of my head:
* No access modifiers (private and public doesn't work - at least not the way you expect it to).
* No Nested classes.
* No Consructors.
* No Threading (thus no syncronized).
* Fewer built-in data structures.
* Garbage collector doesn't handle cyclic references.
* No Runtime Reflection.
* No Dynamic Class Loading.
* No Remote Method Invocation.

Anyway that's pretty much all I can remember, I'm sure someone will join in later with some I've forgotten.


Barbapapa(Posted 2007) [#3]
@FlameDuck: About Multiple Inheritance, that's what I meant by 'same as in Java', sorry for my misleading words.

- No Constructors?
As I understood it, BMax has consructors and deconstructors.
By having a new() method you are eventually telling the compiler what code to perform when an object is created. Constructors can't have parameters. Or what do you mean by constructors?


FlameDuck(Posted 2007) [#4]
By having a new() method you are eventually telling the compiler what code to perform when an object is created.
No. The new() and delete() methods are called after object creation / before deletion, so are not constructors or destructers in the traditional sense of the word, but more convenient methods for setting default values and teardown procedures respectively.


H&K(Posted 2007) [#5]
@Flame,

I think I follow you about constructors. But does that mean in Java that you cannot add an object to a list in the creator because it doesnt exit? Or does it exist by the end of the creator.
That is, a creator has already made the object in Bmax before the New(), but in a real creator you have to make the object yourself?
I ask because I dont really understand any oop language except Bmax.

Thaks in advance


Gabriel(Posted 2007) [#6]
No weak references?


Barbapapa(Posted 2007) [#7]
@FlameDuck, hhmm in Java the constructor is run before the object can be assigned to a reference. So, it's purpose is to help construct itself, before anybody else can use it. What is the difference in BMax. What can you do with the object before it has been assigned to a reference?


marksibly(Posted 2007) [#8]
Hi,

Constructor-wise, the main difference is you can't pass parameters to Blitz constructors, whereas in Java you can.


Barbapapa(Posted 2007) [#9]
A Happy New Year! btw it's raining like hell here in Germany now ;/

@marksibly, yes that's what (browsing through all tutorials) I came up with, too.
Is there a reason why this hasn't been implemented in BMax? I started learning OOP in theory with Java, but don't have enough practice to really know and understand what is and what isn't important in practical programming. Although Method overloading and interfaces do seem quite helpful.

So much information is so scattered around that it's rather difficult for a BMax newbie to find a good start. I hope the Wiki will soon start over again and be somehow moderated. The knowledge power of the community is strong enough as I reckon. But I'm getting OT here, back to OOP in BMax :)

@FlameDuck, could you please elaborate on your points. I didn't understand every point (e.g. No Runtime Reflection, Garbage collector doesn't handle cyclic references.) and what do you see as main benefits in having them?


Mark Tiffany(Posted 2007) [#10]
Runtime reflection is being able to query the structure of an object while running the code. Great for debugging / unit testing. Not sure of a use outside of a dev environment, maybe for building modular code / plugins?

Debugger & cyclic references - the problem here is if you have object A pointing to object B, and B to A. For example where you have parent/child relationships and the parent holds a collection of children, and the children point to the parent. You have to write your own code to manage this to ensure that memory gets freed properly.


Barbapapa(Posted 2007) [#11]
@Mark, thanks allot Mark for the explanation. About cyclic references, this sounds VERY dangerous, I can't imagine this being implemented in Java, haven't read anything about it yet.
Runtime reflection could be useful for debugging, but pretty high end in my opinion, dunno how much time and energy would be needed to implement this.

While we're at it ;) what exactly is meant with 'No Dynamic Class Loading'?


Mark Tiffany(Posted 2007) [#12]
Not 100% sure on that one, but I'm thinking it's probably being able to create an object by name (not code), e.g. in VB *spit* you could do obj=CreateObject("TMyType"). Again, useful for modular design, although you'd likely end up wanting interfaces to be able to do it justice.


FlameDuck(Posted 2007) [#13]
Not sure of a use outside of a dev environment, maybe for building modular code / plugins?
Well that too, but it's most useful for serializing objects and such. Let's say you have a save game functionality in your game. Using reflection, you could write just one function that would save the entire game (the state of all objects) for you recursively. This means that when you change an object or two in your game, you save game routine will still actually work.

Without reflection, any changes to objects need to be changed three places. The place you define them, the place you save them, and the place you load them back in.

While we're at it ;) what exactly is meant with 'No Dynamic Class Loading'?
Wikipedia


Barbapapa(Posted 2007) [#14]
@FlameDuck, but isn't that already achieved with serialization and deserialization? At least in java, the entire object graph is saved and restored.

Dynamic loading of classes directly from JAR files it states there, in BMax there are no packaged source files. Would be handy to have it though. But nobody prevents you from having the sources organized in directories. Of course it would be cool to have for BIG projects. But in Java you have the JVM and that's why you have Jars. I don't think that C++ has this ability, it's compiling, linking and finished, like in BMax. But maybe I am missing something :)


FlameDuck(Posted 2007) [#15]
but isn't that already achieved with serialization and deserialization?
Yes. But how would you serialize / deserialize an object without reflection?


Barbapapa(Posted 2007) [#16]
Isn't this simply a technique to achieve serialization / deserialization? How serialization / deserialization is covered internally doesn't have to bother me seriously as long as the compiler does it.


FlameDuck(Posted 2007) [#17]
Maybe. But reflection is useful for many other things besides.


marksibly(Posted 2007) [#18]

re: constructors with parameters.

Is there a reason why this hasn't been implemented in BMax?


Mainly because I wanted to keep things simple!

When you construct an object, it is actually constructed multiple times - first the superclass is constructed, then this class, then subclasses etc.

This gets a little messy when parameters are involved as you then need a mechanism to pass parameters up to the superclass at construction time, eg:
Type Base
   Method New( x )
   End Method
End Base

Type TDerived
   Method New( x,y,z )
   End Method
End Type

Derived's New has to somehow pass 'x' up to Base's New at construction time. In Java, Derived's New would do something like 'Super.New( x )' before executing super's New.

Not impossible, but just something I decided to leave out in order to keep things simple. Actually, thinking about it now I could have gone for 'non-overloaded constructors with parameters' - ie: if Base.New has one parameter, so must Derived.New. But at the time I was playing with the idea of 'Type objects'...

Similarly, I left out overloading to keep things simple. Most languages with overloading end up with pretty complex rules for selecting the correct function/method at compile time. eg:
Function Func( x:Int )
End Function

Function Func( y:Float )
End Function

Local t:Double=10

Func t

Which Func should be called? Certainly, you can start creating rules such as 'the float one because it's type is nearer' - which logically maps to the current rules - or 'neither because there are multiple versions but no exact match', but once you throw in some inheritance things can get a bit messy.

Another dodgy aspect of overloading is it's typically a 'static' thing that is determined at compile time. This can lead to a few surprises such as...
Function Func( t:Base )
End Function

Funciton Func( t:Derived )
End Function

Local t:Base=New Derived
Func t    'only calls the Base version - careful!

In my time as a C++ coder, I ended up avoiding overloading as much as possible and instead named functions more sensibly - eg: FuncInt() and FuncFloat(). That said, I have since encountered better overloading systems and would probably think twice about leaving it out given the chance again.

As far as reflection is concerned, this is the ability to dynamically query an object to determine the types of it's members - it's fields, consts, methods, globals and functions.

However, for this to be really useful you need some mechanism to actually use these - which is hard. Objective C does this beautifully, but at the price of having to 'interpret' all method calls. Still, it's 'fast enough' for a huge number of situations.

I don't consider reflection to be a cure-all for magic object serialization. Objects will often contain 'extra data' like caches, or other objects that are trickier to reconstruct - for example, how would you serialize a TStream? How was the stream opened? Ditto a TPixmap - where did it come from? A file? A custom routine? Just dumping the contents of the TPixmap is probably not ideal...

Certainly, in some cases a 'blind' serializer would do the trick, but you'd have to be pretty careful with what you threw at it. You could argue that this is better than 'no reflection', but in my opinion the ability to query/call methods on objects is far more interesting and I would have considered reflection broken without it!

Dynamic class loading is really just loading types and the associated code as you need them at runtime - sort of a subset of DLL loading. It's mainly useful for plugins etc - or, god forbid, remote code - but really requires a specialized runtime system - ie: it'd be hard to wedge into Max's compile/link system the way it is. Most languages that support dynamic class loading are either interpreted or use a VM.

I have consider dynamic module loading, but it would involve some overhead - you'd have to basically add a level of redirection for all globals, function, types in a module. Perhaps not too bad...?


Barbapapa(Posted 2007) [#19]
@marksibly, you can't imagine what such insight views of your thoughts are worth, pure gold! Because they help understand why you implemented some things or didn't.
And what I understand is that you would do some things differently today but it isn't possible to do anymore without redoing it from ground up. But you haven't closed the core development completely and that is great. Just imagining how many people are working in the development of Java! And looking at Bmax and PureBasic I can really feel the hard work and devotion going on here, with a very very small crew. You achieved very much!

But enough of this ;) what are your thoughts about interfaces? Are you planning to go deeper into OOP or keep it mixed with the procedural way?


djdee(Posted 2007) [#20]
Hello, i have a question about multiple inheritance. what is it exactly ? As i understood it, its like the following example:

type MyBaseClass
end type

type MyDerivedClass extends MyBaseClass
end type

type MyUltimateClass extends MyDerivedClass
end type


Where MyUltimateClass inherits from both the first classes, right ?


Barbapapa(Posted 2007) [#21]
@djdee, try here: [url]http://en.wikipedia.org/wiki/Multiple_inheritance[/url]
Multiple inheritance refers to a feature of object-oriented programming languages in which a class can inherit behaviors and features from more than one superclass. This contrasts with single inheritance, where a class inherits from only one superclass.



Gabriel(Posted 2007) [#22]
Where MyUltimateClass inherits from both the first classes, right ?

Your definition is correct, but your example is incorrect. In your example, MyUltimateClass does NOT inherit from both the other classes. It only inherits fom MyDerivedClass. To you and I, it inherits from both, because it has the contents of both, but to the compiler, it only inherits from MyDerivedClass. The compiler doesn't care that MyDerivedClass is derived too, all it has to do is is keep track of one superclass for this class.

Multiple inheritance would be where you had a class called car, a class called boat and a class called amphibious-vehicle which inherits from both, though car and boat are unrelated.


djdee(Posted 2007) [#23]
Thanx Barbapappa and Gabriel. I get it :)

@Barbapappa: However, im still abit confused about what you mean by that the overloading is missing. I use some overloading in my code and it works. Maybe i havent explored it enough, because it there seems to be some form of overloading available, but maybe every method still has to have the same parameters in blitzmax ? experimenting now..

Have experimented and found, the parameters have to be the same in order for overloading to work, otherwise i get compile-error..


Barbapapa(Posted 2007) [#24]
@djdee, yes exactly this is what makes overloading. You have several equally named methods in a type which must have all different parameters, and by different I mean so different, that the compiler clearly understands them as different. Then by calling the method with the defined parameters the correct method is automatically executed.