Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Something to do with inheritance.
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
TheOneTrueGod




PostPosted: 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.
Sponsor
Sponsor
Sponsor
sponsor
do_pete




PostPosted: 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.
Delos




PostPosted: 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.
TheOneTrueGod




PostPosted: 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
do_pete




PostPosted: Fri May 05, 2006 11:22 am   Post subject: (No subject)

Delos wrote:
Two seperate arrays defeats the purpose of using inheritence.
How so?
wtd




PostPosted: 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.

code:
Rock(ob(3)).Fall


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.
Delos




PostPosted: 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.
wtd




PostPosted: 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.
Sponsor
Sponsor
Sponsor
sponsor
Delos




PostPosted: 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!
wtd




PostPosted: 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.
Cervantes




PostPosted: 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.
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 11 Posts ]
Jump to:   


Style:  
Search: