OOP Interfaces

BlitzMax Forums/BlitzMax Beginners Area/OOP Interfaces

z80jim(Posted 2006) [#1]
How much flexibility is there in assigning objects to fields?

Here is a simple example.

Type TPlayer

     field weapon : ?

     method attack()
          weapon.attack()
     end method

End Type


I want to be able to assign weapon any object that implements the attack() method. I don't want my Player type to care what the object is that is being sent the attack() message. I don't want to create a TWeapon type and only be able to assign TWeapons to the weapon field.

Is there a generic type I can type my weapon field to that would accept any type of object?

Does this make sense? Would this be like INTERFACES in java? I think Obj-C has something similar also.

Thanks,
Jim


Dreamora(Posted 2006) [#2]
You simply have to define a type like

Type ITWeapon abstract
   method attack() abstract
   ...
end type


Which is extended for any implementation of weapon.

type TSword extends ITWeapon
   method attack()
      ' Do something here
   end method
end type



With the usage of the abstract class, you can guarantee, that the method attack is present as all extending classes must implement it. You do not need to typecast for this usage as well, as the method was present in the "baseclass"


z80jim(Posted 2006) [#3]
But what if I want to have some other object that comes from a different part of the object hierarchy be able to act as a weapon?

Maybe there is a TBook type and I decide it could be used as a weapon. So I add the attack() method to my TBook class. But I can't assign it to my weapon field.

Is there some way to handle this kind of thing?


N(Posted 2006) [#4]
You could use a component-object based entity system.

I posted a somewhat crude one here: http://www.blitzbasic.com/codearcs/codearcs.php?code=1628

Game Programming Gems 5 and the most recent Game Developer Magazine cover this as well.


Dreamora(Posted 2006) [#5]
Yes and no. Its doable, but it will become far harder, if you TBook is not extended from ITWeapon (if you want it to use as weapon, it should be extended from one, otherwise the design is flawed)


In that case you would be forced to use :Object as type and then:

Type TPlayer

     field weapon:object

     method attack()
          if ITWeapon(weapon) <> null
             ITWeapon(weapon).attack()
          elseif TBook(weapon) <> null
             TBook(weapon).attack()
          endif   
     end method

End Type



N(Posted 2006) [#6]
Well, you can do it the messy way (Dreamora's) or the component way (mine).

Components are much more manageable. If you want an object to be useable as a weapon, you simply add a component that allows that.


Dreamora(Posted 2006) [#7]
And how would you do that? Its not like the component system you link to gives exactly no hint on what it is usable for at all (for C++ programmers it might be, but there is a reason I avoided the pointer hacker language No1 ;) )

I see how it would be usefull for objects etc. But in this case, its asked how to execute a specific method of a given object ... Normally that would be done through interfacing, but BM lacks multi inheritance ...

Especially as BM does not allow method pointers, its somehow hard to understand how it should be used in that case here.


N(Posted 2006) [#8]
You call the Update method of a component container and it updates the components with any relevant data you pass to it (my example code doesn't have any arguments for passing an UpdateArgs object, but the idea is that if you really are interested you're going to do some research on the idea, and since I provided a few sources that should get him started).


Dreamora(Posted 2006) [#9]
So it is some type of realtime reflection?
Last time I read of this stuff was with "old" C# where similar (at least to me) stuff was needed to do "generics". Will try to find some informations :-)


N(Posted 2006) [#10]
No, it's more like event handling with classes instead of delegates.


Dreamora(Posted 2006) [#11]
ah, ok ...

Will try to find some infos on it, google wasn't of much help so far, some intelligent place to look for or keywords are welcome ;-)


BlackSp1der(Posted 2006) [#12]
I use the extends and abstract method like Dreamora say.




N(Posted 2006) [#13]
ome intelligent place to look for or keywords are welcome ;-)


Like I said: Game Programming Gems 5 and the most recent Game Developer Magazine


Dreamora(Posted 2006) [#14]
The mag are not that available here in europe.
And for general gem books, I've no money at the moment. Hoped there would be usefull ressources ... will have to check MSDN, as those stuff normally comes from there anyway.


z80jim(Posted 2006) [#15]
How about taking this approach?

Type TWeapon
     method attack()
        print "attack with weapon"
     end method
end type

Type TPlayer
    weapon : TWeapon

    method attack()
         weapon.attack()
    end method

end type



Then I can do two things. If I want to have a weapon in the game I could subclass TWeapon and assign it to the players weapon field like this:


Type TSword extends TWeapon
    method attack()
        print "attack with sword"
    end method
end type

mysword : TSword = new TSWord
player.weapon = mysword



or I could add a TWeapon field to some other object that I can't subclass from TWeapon. Then assign the TWeapon field within this object to the players weapon field.


Type TBook
     field title : string
     field contents : string
    
     field weapon : TWeapon
end type

spellbook : TBook = new TBook
player.weapon = spellbook.weapon



This would seem to be pretty flexible. Just add a TWeapon field to any class I want to weaponize.

Wait. Why even sublcass TWeapon for "real" weapons. Maybe TSword should go like this:

Type TSWord 
    field weapon : TWeapon
end type



Then the assignment to the players weapon field will be consistent with any weaponized object because I am assigning a field of the object to the players weapon in every case.