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

Username:   Password: 
 RegisterRegister   
 Inheritence and Polymorphism
Index -> Programming, Turing -> Turing Help
Goto page 1, 2  Next
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Cervantes




PostPosted: Sat Aug 20, 2005 9:44 pm   Post subject: Inheritence and Polymorphism

Has anyone experimented with Inheritence and Polymorphism in Turing? I've looked at the help file for deferred, but it seems that that will only allow me to redefine (with the same set of parameters) the method in the child class without defining it in the parent class at all. I'd like to do something like this:

Parent:

class PARENT
    export Init

    var my_string : string

    proc Init (s : string)
        my_string := s
    end Init

end PARENT

CHILD:

class FOOBAR
   
    proc Init ()
        % Of course, this isn't the right syntax. 
        % Just trying to convey the idea here.
        PARENT.Init ("Foobar") 
    end Init

end FOOBAR


I want to be able to change the parameters for the child's method and change the code within it. Is this possible? So far, I've only come up with the roundabout method of simply renaming the Parent's method to Parent_Method_Name.

Or have I missed the point of polymorphism? It seems sort of silly though that if I defer a procedure I force myself to rewrite it in all the child classes, and I force myself to make those methods have the exact same parameters as the parent's method.
Sponsor
Sponsor
Sponsor
sponsor
Hikaru79




PostPosted: Sun Aug 21, 2005 12:11 pm   Post subject: (No subject)

I don't have much experience with Turing's specific implementation of object orientation, but I do have other background in that area, so I'll try to answer your questions on a general level.

A procedure's definition does not stop at its name. A procedure's definition includes the name AND the parameters. So if you have two procedures named Init, but one takes a string and one doesn't, they are two seperate procedures and there is nothing you can do about that. It's the way it is meant to be. You cannot overload a method in the subclass if it takes different parameters than its superclass.

When you define a procedure in a subclass that already existed in the parent class, you overwrite it, so to speak.

Or am I misunderstanding your question? Embarassed
Cervantes




PostPosted: Sun Aug 21, 2005 1:39 pm   Post subject: (No subject)

Thanks Hikaru. While Turing doesn't do overloading, what you said affirms that I shouldn't be able to do that, not that I'm doing it the wrong way.

I've decided to go with the roundabout method I mentioned earlier, which I suppose isn't really a roundabout method because it does something quite distinct. I've also found a use for polymorphism in my little program: the Animation procedure. I'm sure I'll find more as I keep working. If anyone's interested, I'm dabbling at making an RTS. I don't actually expect to complete it, or even get a demo of it done; rather, I'm just seeing how far I can get. Razz

Thanks again, Hikaru.
Cervantes




PostPosted: Sun Aug 21, 2005 8:39 pm   Post subject: (No subject)

I'm fairly sure Turing can't do this, but I'm curious if other languages can: is it possible to use polymorphism to add fields to a record in the child classes?
Cervantes




PostPosted: Mon Aug 22, 2005 9:16 am   Post subject: (No subject)

Oh noes!
I'm having grave trouble with the RTS. Specifically, I've come to the point where I have to make multiple units of varying types work together. I need to have a flexbile array of units, but those units could be Footmen or Knights (or others, when I make more). Here's the layout I was hoping to have:
Posted Image, might have been reduced in size. Click Image to view fullscreen.
I would then create a flexible array of pointers to the ANY_OBJECT class, and manage everything by calling the Handle procedure (which is deferred from GENERIC_OBJECT to GENERIC_UNIT and GENERIC_STRUCTURE).

The trouble is, Turing will not allow me to have a class inherit (or impliment, for that matter) multiple files, no matter what. I suppose that only makes sense, as I can't even imagine how things would work otherwise (I'm just hoping they would work my way Razz).

I would love to find some way to make the inheritence and polymorphism approach work. Perhaps I could deferr most methods from the GENERIC_OBJECT class (methods such as Attack, Move, Rotate, Guard, and Build_Unit) to the GENERIC_UNIT (henceforth known as G_Unit) and GENERIC_STRUCTURE classes. G_Unit and GENERIC_STRUCTURE would resolve the methods they need, and leave the other ones as empty. For example, GENERIC_STRUCTURE would resolve the Build_Unit method, but would resolve methods such as Move and Attack as empty procedures.
The flowchart for this approach would look like the above flowchart, but stopping at the third row.

[EDIT]

    Whoops. That wouldn't work. The objects I create with the GENERIC_OBJECT class would not know whether they are supposed to be footmen, knights, or barrackses. The only way I can think of getting around this would be to pass (as a parameter) a string in to the Init procedure of the GENERIC_OBJECT that specifies the type of object (footman, knight, etc.). The Footman and Knight etc. classes would resolve the Init procedure, but all the code for this resolved Init procedure would be wrapped in an if statement: if object_type = "footman" for the footman class. This might work, provided that Turing will call all versions of the deferred procedures (call the Init procedure resolved by the footman and knight etc. classes). I guess there's only one way to find out...
[/EDIT]

[EDIT^2]

    Nope, that's not how Turing works.
    Turing:

    class A
        export Init
        deferred proc Init (s : string)
    end A

    class B
        inherit A
        body proc Init %(s : string)
            if s = "B" then
                put "B Initialized"
            end if
        end Init
    end B

    var p : ^A
    new A, p
    A (p).Init ("B")

    Error on the last line: "Deferred subprogram has not been resolved". Alas, I want it to call all the versions of the resolved procedure (from all of the child classes).
[/EDIT^2]

Failing that, my next approach would be to read everything in from files. I would then have several modules to handle things such as building units and spellcasting. Haven't really thought much on this approach yet.

4/5 posts in this topic. I'm making my own blog! Laughing ... Sorry. Shifty
wtd




PostPosted: Mon Aug 22, 2005 4:53 pm   Post subject: (No subject)

Use a programming language that pays more than lip service to object orientation. Smile
Cervantes




PostPosted: Mon Aug 22, 2005 5:05 pm   Post subject: (No subject)

I'm looking for general ideas. Even if I can't do it, I want to know how!

Are you saying that there are languages that, when a call is made to a deferred procedure in the parent class, will run the resolutions of that procedure in all the child classes?

Better yet, I need multiple inheritence (assuming the flowchart representation would work if I could do multiple inheritence). Does Ruby or Java do this?
wtd




PostPosted: Mon Aug 22, 2005 5:17 pm   Post subject: (No subject)

Ruby and Java only support multiple inheritance via mix-ins and interface inheritance, respectively. If you're looking for a lightweight language that does support MI, you may wish to look at O'Caml or Python.

But it seems like you're just looking for a way to be able to pass Footman or Knight (for instance) to the same function/procedure. Typically, this makes use of the "is a" relationship. A Kight "is a" generic unit, therefore, anywhere you specify a generic unit, you can pass a Knight.

Here's a snippet from the O'Caml toplevel, for instance:

code:
# class virtual generic_unit = object (self)
     method virtual handle : unit
  end;;
class virtual generic_unit : object method virtual handle : unit end
# class footman = object (self)
     inherit generic_unit
     method handle = print_endline "footman#handle"
  end;;
class footman : object method handle : unit end
# let f = new footman in f#handle;;
footman#handle
- : unit = ()
# class knight = object (self)
     inherit generic_unit
     method handle = print_endline "kight#handle"
  end;;
class knight : object method handle : unit end
# let k = new knight in k#handle;;
kight#handle
- : unit = ()
# let foo (gu : generic_unit) = gu#handle;;
val foo : generic_unit -> unit = <fun>
# foo (new knight);;
kight#handle
- : unit = ()
# foo (new footman);;
footman#handle
- : unit = ()
#
Sponsor
Sponsor
Sponsor
sponsor
Cervantes




PostPosted: Mon Aug 22, 2005 5:41 pm   Post subject: (No subject)

Excellent, wtd. What you said about the "is a" relationship gave me the idea of creating a new object of the KNIGHT class using a pointer to GENERIC_OBJECT. It works. Very Happy Now to see how far this can take me.

That O'Caml code: is that sort of like Ruby's irb?
wtd




PostPosted: Mon Aug 22, 2005 5:45 pm   Post subject: (No subject)

Cervantes wrote:
That O'Caml code: is that sort of like Ruby's irb?


Pretty much.
wtd




PostPosted: Mon Aug 22, 2005 8:24 pm   Post subject: (No subject)

Of course, you should realize that with the likes of Ruby or Python, you have duck typing, and don't necessarily need a strict inheritance hierarchy.

code:
irb(main):001:0> class Knight
irb(main):002:1>    def handle
irb(main):003:2>       puts "knight#handle"
irb(main):004:2>    end
irb(main):005:1> end
=> nil
irb(main):006:0> class Footman
irb(main):007:1>    def handle
irb(main):008:2>       puts "footman#handle"
irb(main):009:2>    end
irb(main):010:1> end
=> nil
irb(main):011:0>
irb(main):012:0* def foo(gu)
irb(main):013:1>    gu.handle
irb(main):014:1> end
=> nil
irb(main):015:0> class Bar; end
=> nil
irb(main):016:0> foo(Knight.new)
knight#handle
=> nil
irb(main):017:0> foo(Footman.new)
footman#handle
=> nil
irb(main):018:0> foo(Bar.new)
NoMethodError: undefined method `handle' for #<Bar:0x2dad7e8>
        from (irb):13:in `foo'
        from (irb):18
irb(main):019:0>
Tom West




PostPosted: Mon Aug 22, 2005 9:31 pm   Post subject: (No subject)

I'm not entire certain why you would want multiple inheritance in this particular example. A standard class hierarchy would do fine. If you have a lot of cross references between classes, you will need to split the declaration and the implementation (see "implement by" in the on-line help), but you may well be able to get around that at all.

(Besides, personal opinion here, multiple inheritance causes far more problems than it solves. There are solid reasons why it's been left out of almost all modern OO languages.)

Can you elaborate why you need the bottom part of the hierarchy?

Here's a little bit of code that uses your example to produce a really simply game using your hierarchy. The main concepts used are casting an GenericObject to a subclass so that you can use that subclass' exported procedures and functions.

Anyway, let me know if this example needs to be elaborated upon.



classexample.t
 Description:

Download
 Filename:  classexample.t
 Filesize:  4.78 KB
 Downloaded:  116 Time(s)

wtd




PostPosted: Mon Aug 22, 2005 10:42 pm   Post subject: (No subject)

Tom West wrote:
There are solid reasons why it's been left out of almost all modern OO languages.


Not true at all. Smile

Python, O'Caml, and Eiffel among others feature multiple inheritance.
rizzix




PostPosted: Tue Aug 23, 2005 12:56 am   Post subject: (No subject)

*cough*most*cough*ehm yea.. bad throat Laughing Wink
wtd




PostPosted: Tue Aug 23, 2005 3:04 am   Post subject: (No subject)

This also supposes that there's anything even remotely modern about languages like Java and C#. Razz

New? Yes. Modern? That's highly debatable.
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 2  [ 30 Posts ]
Goto page 1, 2  Next
Jump to:   


Style:  
Search: