Classes Part II - Object Interaction
Author |
Message |
Cervantes
|
Posted: Tue Jan 10, 2006 10:24 pm Post subject: Classes Part II - Object Interaction |
|
|
Classes Part II:
Interaction of Objects
At the end of this tutorial, you will find an attached .zip. This file contains pretty much all the code we are using in this tutorial, as well as the image that outlines the PopMachine's input/output.
An Introduction
So far, we've created programs that have a single class. (Be sure to have read Classes Part I.) We have not had any room for interaction of objects, either because we only made one object (instance of our only class), or because there was no need for objects of the same class (our only class) to interact, such as the button objects that I hope you made.
In this section, we will look at how objects may interact with each other. Consider a Pop Vending Machine, for example. It is an object that accepts money objects, processes your input (the buttons you push), and outputs a can of carbonated sugar. Let's write a Turing program to explore this idea, using the Pop Machine example.
A bit of Theory
We want our Pop Machine to accept Money objects and dispense Pop objects. We will give the Pop Machine a purchase method, and it will take two parameters: 1) a Money object and 2) a Pop object. It will accept the Money object, make change if necessary, and dispense the Pop object if enough Money has been given.
Allow me to highlight an idea from the last paragraph. A method in the PopMachine class will accept objects as parameters. How do we do that? Recall from the last section what our objects were represented as: pointers to a certain class, in this case the Money or Pop class. So, our parameters will have the variable type
or
Let's write some abstract code to see if this will work.
code: |
class Foo
export message, set_message
var message := ""
proc set_message (value : string)
message := value
end set_message
end Foo
class Bar
export message_from_Foo
fcn message_from_Foo (obj : pointer to Foo) : string
result Foo (obj).message
end message_from_Foo
end Bar
var f : ^Foo
new Foo, f
Foo (f).set_message ("Hello from the Foo class.")
var b : ^Bar
new Bar, b
put Bar (b).message_from_Foo (f)
|
When you run this code, you will get two warnings, since "Foo" appeared twice in the Bar class, but Foo was not imported. We have to import Foo into the Bar class. Let's do that.
code: |
class Foo
export message, set_message
var message := ""
proc set_message (value : string)
message := value
end set_message
end Foo
class Bar
import Foo
export message_from_Foo
fcn message_from_Foo (obj : pointer to Foo) : string
result Foo (obj).message
end message_from_Foo
end Bar
var f : ^Foo
new Foo, f
Foo (f).set_message ("Hello from the Foo class.")
var b : ^Bar
new Bar, b
put Bar (b).message_from_Foo (f)
|
Note that things like import and export always come at the beginning of the class (or module, or other structures), and that import always comes before export.
This may seem like an awfully long, complex way to put something to the screen, but this is just the beginning. If you made a Button or TextField class, or any other class, as the exercise to the last section, you should have realized the power of object oriented programming by now. It is neat, highly structured and organized, and repetition is easy--we can easily create many instances of the same class, and we therefore save ourselves coding.
With this initial example in mind, let's make our PopMachine, Money, and Pop classes. There's really nothing new in it than in the above code, but it shows this in a more practical light, so it is worth examining.
The Pop Machine Outline
In case we're still not clear on how the Pop Machine will work, here is a graphical representation.
We have two inputs: The Money object that we drop into the coin/bill slot, and our pop request. This is usually in the form of hitting a button, but in this example we will be more blunt: we will directly pass a Pop object (such as a Coke) into the purchase function of the PopMachine object.
The Pop Machine Code
code: |
class Money
export set_money, amount
var amount : real
proc set_money (value : real)
amount := value
end set_money
end Money
class Pop
export set_name, set_cost, name, cost
var name : string
var cost : real
proc set_name (value : string)
name := value
end set_name
proc set_cost (value : real)
cost := value
end set_cost
end Pop
class PopMachine
import Money, Pop
export purchase
fcn make_change (amount, cost : real) : real
result amount - cost
end make_change
fcn purchase (money_given : ^Money, pop_requested : ^Pop) : string
var change := make_change (Money (money_given).amount, Pop (pop_requested).cost)
var pop_name := Pop (pop_requested).name
if change < 0 then
result "You have not given enough money for a " + pop_name + ". Please insert $" + realstr (abs (change), 0) + " more."
elsif change = 0 then
Money (money_given).set_money (0)
result "Thank you for your purchase. Enjoy your " + pop_name + "."
else
Money (money_given).set_money (Money (money_given).amount - Pop (pop_requested).cost)
result "Thank you for your purchase. Your change is $" + realstr (change, 0) + ". Enjoy your " + pop_name + "."
end if
end purchase
end PopMachine
var caf_vendor : ^PopMachine
new PopMachine, caf_vendor
var cash : ^Money
new Money, cash
Money (cash).set_money (1.50)
var coke : ^Pop
new Pop, coke
Pop (coke).set_name ("Coke")
Pop (coke).set_cost (1.25)
put PopMachine (caf_vendor).purchase (cash, coke)
put "You now have $", Money (cash).amount, "."
|
The Pop Machine Options
There are a few ways the purchase method could work. It could result (read: return) a Pop object, which seems logical. But then there's the question of your change. If spitting out a can of pop is an example of "resulting" an object, so too is spitting out your change. Thus, if we want to "result" the Pop and Money, we'd need to "result" an array that contains two objects: the Pop and the Money.
Alternatively, we could define a procedure in the PopMachine class to drop the Pop object to the bottom "bin", and another procedure to drop the Money objects (the change) to the pick-up area. The purchase procedure would call these two procedures (or perhaps only call one of them, if exact change was given; or perhaps call none of them, if not enough change was given).
Further Studies
In this section of the tutorial we have learned how objects may interact. The key idea to remember is that to integrate a type of object into the framework of another object (ie. into that object's class), the variable type is pointer to ClassName, where ClassName is the name of the class of the object we wish to interact with our current object. To do this, we have to import ClassName.
In Part III, we will learn how to create a network of classes, using inheritance. We will also look at polymorphism. These are powerful concepts, and we shall use them to create the basis for working with the items of an RPG.
Description: |
Contains code and images used in this tutorial. |
|
Download |
Filename: |
Classes Part II.zip |
Filesize: |
13.71 KB |
Downloaded: |
601 Time(s) |
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
|
|