Something to do with inheritance.
Author |
Message |
TheOneTrueGod
![](http://www.drmcninja.com/images/mcninjab3.jpg)
|
Posted: Thu May 04, 2006 6:34 am Post subject: Something to do with inheritance. |
|
|
Allright, basically, I have two objects that are a child of another object, and I am creating an array of these at "random". For simplicities sake, I will show this using a very simple example:
code: |
class Object
export Create, DrawMe
var x, y : int
procedure Create (x_, y_ : int)
x := x_
y := y_
end Create
deferred proc DrawMe
body procedure DrawMe
drawfilloval (x, y, 10, 10, black)
end DrawMe
end Object
class Jetpack
inherit Object
procedure Fly
y += 1 %Jetpacks tend to move up, therefore...
end Fly
end Jetpack
class Rock
inherit Object
procedure Fall
y -= 2 %Rocks don't tend to move up as much
end Fall
body procedure DrawMe
drawfilloval (x, y, 10, 10, grey)
end DrawMe
end Rock
var ob : flexible array 1 .. 0 of ^Object
for i : 1 .. 10
new ob, upper (ob) + 1
if Rand.Int (1, 2) = 1 then
new Rock, ob (upper (ob))
else
new Jetpack, ob (upper (ob))
end if
ob (upper (ob)) -> Create (Rand.Int (100, maxx - 100), maxy div 2)
end for
View.Set ('offscreenonly')
loop
for i : 1 .. 10
ob (i) -> DrawMe
ob (i) -> %What can go here? (See rest of post for details)
end for
View.Update
Time.DelaySinceLast (50)
cls
end loop
|
See the line near the end, "what can go here?". If its a jetpack, I want to call the procedure "Fly", but if its a rock, I want to call the procedure "Fall". How can I detect what I should call?
The only solution I have though of so far is to name the two procedures the same thing, but then I run into some problems in more complicated code. For example, I don't want my sword to decrement from an ammo count, but I may want my machine gun to. |
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
do_pete
![](http://i38.photobucket.com/albums/e112/do_pete/1943.gif)
|
Posted: Thu May 04, 2006 6:59 am Post subject: (No subject) |
|
|
You could make two separate flexible arrays or have a boolean in the Jetpack and Rock classes that would id them. |
|
|
|
|
![](images/spacer.gif) |
Delos
![](http://www.members.shaw.ca/rfolz/delos_avatar.gif)
|
Posted: Thu May 04, 2006 10:52 am Post subject: (No subject) |
|
|
do_pete wrote: You could make two separate flexible arrays or have a boolean in the Jetpack and Rock classes that would id them.
Two seperate arrays defeats the purpose of using inheritence.
Some form of ID isn't such a bad idea though. I don't think it would be a huge problem to create a single "DoAction" deferred proc that is common to all your classes.
If you need to pass parameters to them, there are a couple of options:
- looking at Cervantes Classes tut, you can see that there are times when you could pass a whole slew of parameters, but only consider a few. So:
code: |
proc DoAction (_x, _y, _ammo, _shield : int)
x += _x
ammo -= _ammo
end DoAction
|
Here, you pass four parameters, but only utilize 2.
- you could be a little more concise, and create a type that would encapsulate all the necassary parameters to be passed. You would then create a temporary one that housed the necassary changes you'd need, and pass that:
code: |
type obj_cloak :
record
x, y, ammo, shield : int
end record
%...
var temp : obj_cloak := initialize_oc (10, 0, -5, 0)
% And of course, initialize_oc would be a fcn created somewhere
% around here...^_^
myObject -> doAction (temp)
% Where doAction looked like:
% proc doAction (_obj : obj_cloak)
% ...
|
Again, this method leaves you with a set of values, only some of which are useful.
- a third possible method, one that I encorporate quite frequently, is to use a single paramter that masks the commands...
code: |
proc doAction (_action : string)
%...
myObject -> doAction ("_x:5;_ammo:-2")
|
In other words, in the same fashion that setscreen() works in. It's quite the useful method, since in each of your resultant doAction procs (in each class), you can index and parse out only the necassary commands. So, if someone mistakenly assigns a "fall" to a Jetpack, it would ignore it (or you could be more thorough and actually return an error msg if an inappropriate command is given).
Think of it as scripting.
The only problem you could run it to is if your scripts exceed 255 chars...but that's not likely to happen unless you're being supurfluous. In which case you could just use a dynamic array. |
|
|
|
|
![](images/spacer.gif) |
TheOneTrueGod
![](http://www.drmcninja.com/images/mcninjab3.jpg)
|
Posted: Thu May 04, 2006 1:27 pm Post subject: (No subject) |
|
|
Awesome, I'll see which one will suit my needs best.
Thanks for the help ![Very Happy Very Happy](http://compsci.ca/v3/images/smiles/icon_biggrin.gif) |
|
|
|
|
![](images/spacer.gif) |
do_pete
![](http://i38.photobucket.com/albums/e112/do_pete/1943.gif)
|
Posted: Fri May 05, 2006 11:22 am Post subject: (No subject) |
|
|
Delos wrote: Two seperate arrays defeats the purpose of using inheritence. How so? |
|
|
|
|
![](images/spacer.gif) |
wtd
|
Posted: Fri May 05, 2006 12:44 pm Post subject: (No subject) |
|
|
I don't see two separate arrays in that code. Am I missing something?
Oh, and you're wondering about a fairly common problem programmers run into in object-oriented programming in statically-typed languages (Turing falls into this category).
You have created an array of poointers to objects of type Object.
Since Rocks and JetPacks are Objects (via the inheritance relationship), then of course you can add them to this array.
However, Turing simply sees those things as Objects, since that is all the information you provided when you declared the array.
As a result, you cannot implicitly treat any given object in the array as anything other than an Object.
However, explicitly you may. Let's say the third element in "ob" is a Rock. I hope I have the syntax right.
Here you've now told it that the object is a Rock. Thus you can call it's Fall method.
Of course, problems arise if you do this and the object is not in fact a Rock. |
|
|
|
|
![](images/spacer.gif) |
Delos
![](http://www.members.shaw.ca/rfolz/delos_avatar.gif)
|
Posted: Fri May 05, 2006 1:04 pm Post subject: (No subject) |
|
|
do_pete wrote: Delos wrote: Two seperate arrays defeats the purpose of using inheritence. How so?
What I meant was by using inheritence one would be able to use a single array of Objects, as opposed to two seperate arrays for each of Object's children. This means that things are a little more centeralized, and later checks/initializations/etc can be done in a simple for loop.
@wtd, could you expand a little on the differences between implicit and explicit treatment of objects as either Objects or (eg) JetPacks...? Or perhaps direct me to the relevant tut. |
|
|
|
|
![](images/spacer.gif) |
wtd
|
Posted: Fri May 05, 2006 1:19 pm Post subject: (No subject) |
|
|
It all boils down to the "is a" relationship.
Let's say I have Parent and Child classes. Child inherits from Parent. Therefore Child is a Parent.
If I declare a variable as a pointer to Parent...
code: | var foo : pointer to Parent |
Now I can "new" this as either a Parent object or a Child object.
However, since I declared the variable itself as Parent, Turing can only treat this as a Parent. Therefore any methods Child has that Parent does not will be unavailable. Those methods only become available if we explicitly tell Turing that foo is in fact a Child object. |
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
Delos
![](http://www.members.shaw.ca/rfolz/delos_avatar.gif)
|
Posted: Fri May 05, 2006 3:27 pm Post subject: (No subject) |
|
|
Ah, this sounds vaguely familiar now. I believe Cervantes touched upon it in his Classes tut. Quite limiting...ah well, I guess that's what happens when using a language like Turing.
Thanks! |
|
|
|
|
![](images/spacer.gif) |
wtd
|
Posted: Fri May 05, 2006 3:32 pm Post subject: (No subject) |
|
|
Such happens in any language that is statically-typed and where variables as well as values are typed.
If you only tell the compiler/interpreter that the foo variable is a Parent, and give it no indication to the contrary (the type of the value it points to deals with the value, rather than the variable), then it cannot safely treat the variable as anything other than a pointer to a Parent object.
The same occurs in many other languages, including notably Java and C++. It should be noted, however, that this behavior is not necessarily integral to object-oriented programming, as many throughly OO languages and environments are not so burdened, owing to their lack of statically-typed variables. |
|
|
|
|
![](images/spacer.gif) |
Cervantes
![](http://compsci.ca/v3/uploads/user_avatars/1023105758475ab2e040bde.jpg)
|
Posted: Sat May 06, 2006 11:54 am Post subject: Re: Something to do with inheritance. |
|
|
TheOneTrueGod wrote: The only solution I have though of so far is to name the two procedures the same thing, but then I run into some problems in more complicated code. For example, I don't want my sword to decrement from an ammo count, but I may want my machine gun to.
Why can't you just redefine this method in the Sword and Gun classes? so that the Sword doesn't reduce the ammo count but the Gun does. Actually, the Sword shouldn't even have an ammo variable.
Of course, this task would be made much easier with a thing like super, as discussed in the tutorial. |
|
|
|
|
![](images/spacer.gif) |
|
|