Classes, method or any thing to do with classes

Monkey Archive Forums/Monkey Tutorials/Classes, method or any thing to do with classes

julesd(Posted 2012) [#1]
I am having a hard time understanding classes, how it works, when to use it, where to use it.

Is there any one, who can write a tutorial on this, that is simple to understand? Thank you.
i would like to know
classes
method
field
any thing else that may be handy with classes.


Midimaster(Posted 2012) [#2]
let me try to explain it from a beginners viewpoint:

1. A Class is a namespace:

A class is a piece of code, that works independent of other code. You can use variable names twice without colliding with the other variable names:

[monkeycode]Global A%

Class MyGame
Global A%
End[/monkeycode]

So it is very helpful to encapsul "modules" of yours game, that you may use in more than one game inside classes. F.e. you can use your "licence" class or a "translation" class in all your projects.


2. A Class is a sort of TYPE
You can also see classes like a user defined variable type. In this case a class descripes a bunch of variables descriping a actor in a game:
[monkeycode]Class EnemyClass
Field X%, Y%, Pic:Image, Energy#, Name$
End[/monkeycode]
This offers you the chance to define your own "variables" which have more properties then only store one integer number:
[monkeycode]Enemy1:EnemyClass= New EnemyClass
Enemy1.X=45
Enemy1.Y=500
Enemy1.Pic=LoadImage(...
Enemy1.Energy=100
Enemy1.Name="Thor"[/monkeycode]
To use such a user defined type you will create new "instances" of your type.
[monkeycode]Enemy1:EnemyClass= New EnemyClass
Enemy2:EnemyClass= New EnemyClass
[/monkeycode]
You can compare this with creating two INTEGER variables:
[monkeycode]A:INT= New INT
A=45
B:INT= New INT
B=90[/monkeycode]
Using the keyword "Field" in the definition (above) means, that you can use X% as often as you want without colliding with other instances of your type.
[monkeycode]Enemy1:EnemyClass= New EnemyClass
Enemy1.X=45
Enemy2:EnemyClass= New EnemyClass
Enemy2.X=90[/monkeycode]

3. Using instances
You now can use this instances as a whole:
[monkeycode]Enemy1:EnemyClass= New EnemyClass
Enemy1.X=45
Enemy2:EnemyClass= New EnemyClass
Enemy2.X=90
Enemy2=Enemy1
Print Enemy2.X[/monkeycode]
This is corresponding to
[monkeycode]A:INT=1
B:INT=2
B=A
Print B[/monkeycode]

4. Functions
Those Classes can have functions inside, that work independent from functions with the same name outside.

[monkeycode]Class EnemyClass
Global CommonImage:Image
Field X%, Y%, Pic:Image, Energy#, Name$

Function LoadOneImage(File$)
CommonImage=LoadImage(File$)
End

Function CreateOne:EnemyClass(X%,Y%,Name$)
Local loc:EnemyClass= New EnemyClass
loc.X=X
loc.Y=Y
loc.Pic=CommonImage
loc.Energy=100
loc.Name=Name
Return loc
End
End[/monkeycode]
The first function will load a GLOBAL image will can be accessed by all instances of the Class. The second function will create a instance and fill the fields with values, then return this instance back to the main program. The main program would look like this:

[monkeycode]EnemyClass.LoadOneImage("test.png")
Enemy1=EnemyClass.CreateOne(45,500,"Thor")[/monkeycode]

5. Methods
Methods are "functions" that belong to one instance of the Class. The Method can access only the fields of "its" instance:

[monkeycode]Class EnemyClass
Global CommonImage:Image
Field X%, Y%, Pic:Image, Energy#, Name$

Method Move(Direction%)
X=X+Direction
End
End[/monkeycode]

You can call this Method to change values of one Enemy:
[monkeycode]Enemy1:EnemyClass= New EnemyClass
Enemy1.X=45
Repeat
Enemy1.Move(-1)
Until....
[/monkeycode]


Ask, if you want to know more....


MikeHart(Posted 2012) [#3]
Hi julesd,

what is your programming background? Did you work through the tutorials that ship with monkey? If you are on OSX, some didn't open in V66 because they are PDFs. Run V67b to open them on OSX.


julesd(Posted 2012) [#4]
I am using Windows 8

I'm not a bad programmer, but I just seam to have a bit of a problem with classes.

Would I use classes only to create Object oriented programming?, can classes be in the main program or are they generally imported?, stuff like that.

@Midimaster

Thanks, starting to under stand a bit more.


Beaker(Posted 2012) [#5]
Classes can be in the main program or imported, doesnt matter either way. They are the way to create object-orientated programming. Very useful they are too. Once you understand them they make programming easier, more readable, easier to debug, more reusable, use memory better etc etc.


Tibit(Posted 2012) [#6]
Have you seen the Monkey video tutorials by invaderJim?

Here it the one starting with Object Oriented Programming in Monkey:
http://www.youtube.com/watch?v=7sZ-iW9jzRI&feature=share&list=PL7A005F9D856022B8


Kauffy(Posted 2012) [#7]
I strongly second going through invaderJim's videos. Follow along in the tutorials and you will start to pick it up.

Class/objects/fields, etc. are a little tricky as a concept. If you're used to either top-down or event-driven programming, then an OO approach may seem confusing at first, but for anything larger than the simplest little app, it makes the going much easier in the long run.

You could write all of an object-oriented program in one file, yes-- all your classes, your mains, etc. You could even cut-and-paste all the modules you would want to include in there.

The benefit, though, is that if you design your classes well, you can put them into separate files and forget about them. When you're working on one part of your code, you can forget all about the classes/things you're not interested in, instead of scrolling over them or jumping around. It makes it much easier to work in 10,000 lines of code when no single file is ever more than 300-500 lines, for example.


RetroRusty(Posted 2013) [#8]
Can someone please explain what a Method is in as simple terms as possible (as though you were explaining it in layman's terms)? I've looked at invadersJim's video on it and he doesn't explain it so that I can understand and he explains it fast and I don't get it.

I know what a Class is and it's purpose but can't get what a Method is for and why you need it.


ziggy(Posted 2013) [#9]
A Method is a function that has access to the fields of a class. A function does not have access to the filed of a class.

Example:

Class MyClass
   Field var:Int = 2
   Function SayHello()
      Print "Hello"
      'Print var   'Uncomment this to see it fail. var can't be accessed here, it's a field!
   End
   Method DoubleTheValueVar()
      var=var*2
   End
End

Function Main()
   MyClass.SayHello() 'This is correct, as SayHello is a function, it does not need any instance to be created. It's just like any other function, but happens to be inside a class.

   MyClass.DoubleTheVarValue()   'compiler error. Methods access fields, so it requires a class instance.

   Local MyInstance= New MyClass
   Local MyOtherInstance = New MyClass
   MyInstance.DoubleTheVarValue()   Right, we're doubling the var value of the variable "MyInstance"
   
   Print MyInstance.value
   Print MyOtherInstance.value

End


Once you comment out the compiler error line, you should get an idea of what it does.

It should output:
4
2

Haven't tested, as I'm far from my computer right now, but I hope you get the idea.


Midimaster(Posted 2013) [#10]
If you think about a Class "Car" you can create single Cars. This cars can do all the same things like driving around. With Methods you can drive them in individual directions. The corresponding variables are called "Fields":

MyCar:Car = New Car
YourCar:Car = New Car

Repeat
     MyCar.Drive 1,0
     YourCar.Drive 0,1
Forever


Class Car
   Field X%, Y%

   Method Drive:Void(Xadd%,Yadd%)
      X=X+Xadd
      Y=Y+Yadd
   End
End


A Method "knows" the car who is calling and will differ the fields from MyCar and YourCar. In my sample MyCar would drive to the east and YourCar to the South.


computercoder(Posted 2013) [#11]
First, you need to know what a "Class" is. It is the object of which you are trying to make. This can be ANYTHING.

For my example, it will be a BOX.

Class Box

End


Now, you need to know specific things about this box. What size is it, in Height, Width and Length. Perhaps you need to know about its color or what type of material it is made up of. These are known as Properties. In Monkey, a "Property" is called a "Field".

Class Box
  Field Height:Float = 0
  Field Width:Float = 0
  Field Length:Float = 0
  Field Color:Int = 0
  Field TypeOfMaterial:String = "Cardboard"
End


There are actions that you want to perform with any box made from this "Class", but can only be performed after the BOX is created. This is called a METHOD. An example of a METHOD would be "OpenBox" or "CloseBox"

Class Box
  Field Height:Float = 0
  Field Width:Float = 0
  Field Length:Float = 0
  Field Color:Int = 0
  Field TypeOfMaterial:String = "Cardboard"
  Field BoxIsOpen:Bool = False

  Method OpenBox()
    BoxIsOpen = True
  End

  Method CloseBox()
    BoxIsOpen = False
  End

End


If there is an action that you need to perform that does not require the BOX to be created, then this is called a FUNCTION. A Function is special type of Method that can perform actions using the properties and methods within the Class. You may just need to do some math that allows you to find the volume of any box, but don't need the actual box, just the dimensions.

In this example, I am not using any of the methods or fields within my function. Everything I need is passed in the Function call.

Class Box
  Field Height:Float = 0
  Field Width:Float = 0
  Field Length:Float = 0
  Field Color:Int = 0
  Field TypeOfMaterial:String = "Cardboard"
  Field BoxIsOpen:Bool = False

  Method OpenBox()
    BoxIsOpen = True
  End

  Method CloseBox()
    BoxIsOpen = False
  End

  Function Volume:Float(length:Float, width:Float, height:Float)
    Return length * width * height
  End
End


With this "Class", you have defined the basics for what is needed to make a box with a given set of dimensions, material type, and can determine if it is open or closed. Additionally, you can calculate the volume for a box without needing to create the box.

If you want to create an instance of a class and define its fields at the same time, you need to pass a New() Method. If you are allowing the class to be created without providing values upon creation, then you will also need to provide the New method with and without parameters.

Class Box
  Field Height:Float = 0
  Field Width:Float = 0
  Field Length:Float = 0
  Field Color:Int = 0
  Field TypeOfMaterial:String = "Cardboard"
  Field BoxIsOpen:Bool = False

  Method OpenBox()
    BoxIsOpen = True
  End

  Method CloseBox()
    BoxIsOpen = False
  End

  Function Volume:Float(length:Float, width:Float, height:Float)
    Return length * width * height
  End

  Method New()
    ' Nothing needed here
  End

  Method New(length:Float, width:Float, height:Float)
    Self.Length = length
    Self.Width = width
    Self.Height = height
  End
End


To access a Field (property):
Local MyBox = New Box(15,10,10)

If MyBox.BoxIsOpen
  Print "Box is Open!"
Else
  Print "Box is Closed!"
End


To access a Method:
Local MyBox = New Box(15,10,10)
MyBox.OpenBox()

If MyBox.BoxIsOpen
  Print "Box is Open!"
Else
  Print "Box is Closed!"
End



To access a Function:
Local Volume = Box(15,10,10)
Print "Volume is: " + Volume



Hope this makes sense and helps :)

[EDIT] I *just* realized that I had my OpenBox() and CloseBox() returning a Bool, which is incorrect. These are assigning only methods and not returning values. I corrected the code, should anyone else be following this thread :)


RetroRusty(Posted 2013) [#12]
Thanks for all the help with this.

@computercoder In your example do you not need to have an instance of the Box Class before you can access any of the Functions from within the Box Class?

So if I'm correct, a Method can access the Field's within a Class but a Function can not? In order to call a Method you have to first have an instance of the Box Class (Local MyBox = New Box) but this is not needed to access a Function from within a Class?

What is the point in having Functions within a Class? Could you just not use Methods for anything that you wanted to do?


computercoder(Posted 2013) [#13]

In your example do you not need to have an instance of the Box Class before you can access any of the Functions from within the Box Class?


You do NOT need to have an instance of the Box class when using the Function(s) within the class.


So if I'm correct, a Method can access the Field's within a Class but a Function can not?


In Monkey, this is true.


In order to call a Method you have to first have an instance of the Box Class (Local MyBox = New Box) but this is not needed to access a Function from within a Class?


Again, true.


What is the point in having Functions within a Class?


The point of this is so you can make a framework from related items of functionality in a nice neat wrapped up package.

Let's proliferate on this further.

Let's say you have a group of routines that are all related to each other, but do not necessarily rely upon one another to perform their functionality. Furthermore, you don't want to make an instantiated object to access at them. What can you do?

You COULD make a bunch of functions stuck in a source file that has global access by all parts of your code. Sure this would work, but its very messy. This resembles spaghetti code where functions are tossed about and there's no easy way of sifting through it all. How would you know what belongs with what? What if you have several functions that do similar tasks? How do you know easily which one is the perfect fit for what you are trying to achieve?

Examples:
Draw()
DrawPlayer()
DrawEnemies()
DrawWeapons()
DrawItems()
etc...

It doesn't seem so bad, but you will have one HUGE file and after a while it will be very hard to read through.

You COULD make a class that groups their functionality together. So you put all the functions that are closely related together, and now you access them by the class name (which would be named something appropriate towards the functionality it contains) followed by a "." and then the function call. You won't need to instantiate the class, but now you'd easily know what its doing and where its found,

Consider this:
Using the non-class structured function:
Render()

Using a class structured function:
Engine.Render()

JUST from the glance, can you tell me what the first one does vs the second one? Really, they both RENDER, but what exactly would you expect each Render and Engine.Render() to be rendering?

These area rhetorical questions, but ones you need to make when you design your apps. How can you design the app so its easy to understand and maintain?

Consider the Visual Studio .NET frameworks. I'm not sure how familiar you are with this, but they use the same concept there. Classes such as String provide BOTH instantiated and un-instantiated parts. Forgive me as its been eons since I've actually written Visual Basic.NET code.
Dim strString as String = "I am a string"
Print strString
Print String.Length(strString) 
Print String.Compare("Test","This")

The point here is that everything within the String class pertains to the String OBJECT. You will not find anything outside of dealing with a string contained within the functionality, be it a function or a method that doesn't have relevancy with a String.

Additionally, I haven't discussed SCOPE. Scope will be a key thing here. When you want to black-box code, you will want some functions public while others are private. All Functions in a class can call the other functions to the same class without referencing the class itself.

While you CAN just stick to using methods in classes and making it where you need to create instances of them to get to their methods, you can make it simpler on you by also providing functions to help you along the way that BELONG to what the class is intended for.


Midimaster(Posted 2013) [#14]
My main reason for using functions instead of classes is, because I reach the "master" level of all instances:

back to my car example:

The function StartUp() sets common variables like the common shape of the car for painting them. Also important: a list where all cars are collected.

I also use a function CreateOne() to create a new car, set its fields and return the instance.

One of my main reason for functions is to go through all cars for painting them or moving them. See DrawAll() or DriveAll():

Car.StartUp "Car.png"
MyCar:Car = Car.CreateOne(100,100)
YourCar:Car = Car.CreateOne(200,100)

MyCar.SetSpeed 1,0
YourCar.SetSpeed 0,1

Repeat
     Cars.DriveAll
     Cars.DrawAll
Forever


Class Car
   Global Shape:Image
   Global Cars:List<Car>

   Field X%, Y%, SpeedX%, SpeedY%

   Function StartUp:Void(File$)
        Shape=LoadImage(File$)
        Cars= New List<Car>
   End


   Function CreateOne:Car(X%,Y%)
      locCar= New Car
      locCar.X=X
      locCar.Y=Y
      Cars.AddLast locCar
      Return locCar
   End


   Method SetSpeed:Void(Xadd%,Yadd%)
      SpeedX=Xadd
      SpeedY=Yadd
   End


   Function DriveAll:Void()
      For local locCar:Car= Eachin Cars
         locCar.Drive
      Next
   End


   Method Drive:Void(Xadd%,Yadd%)
      X=X+SpeedX
      Y=Y+SpeedY
   End


   Function PaintAll:Void()
      For local locCar:Car= Eachin Cars
         locCar.Paint
      Next
   End


   Method Paint:Void()
      DrawImage Shape,X,Y
   End

End




RetroRusty(Posted 2013) [#15]
Thanks for explaining that as simple as possible. I believe that I have a better understanding of Method's now, even though I'm not completely okay with them, I know at least the point of them.


ziggy(Posted 2013) [#16]
I believe that I have a better understanding of Method's now, even though I'm not completely okay with them, I know at least the point of them.
Most of us, when we start with OO programing, feel it's weird at the beginning, but after some time, it'll grow on you and you'll see how good it is to code in OO style, specially when a project grows.


Loofadawg(Posted 2016) [#17]
Brushing up...relearning all this stuff. Amazing how I can forget all this stuff when I don't use it.

Here are my questions, functions in a class cannot access the fields of the class unless:

1) the field is set to global inside the class ?
Class EnemyClass
     Global CommonImage:Image
     Field X%, Y%, Pic:Image, Energy#, Name$

     Function LoadOneImage(File$)
          CommonImage=LoadImage(File$)
     End


2) is CommonImage still considered a Field of the class event though it's not proceeded by the Field keyword ?

3) a function does though have access to fields of the instance of the object that is calling it ?


Again this is so weird that I have forgotten most of this. I had an app I was working on that mimicked the scoring mechanism of Matching With Friends. I was using Classes, Methods and Functions then. Then my computer bit the dust and I left it all behind for nearly a year.

Please help get me back up to speed guys. Thanks !!


Jesse(Posted 2016) [#18]
Globals with in the class work similarly as in procedural programming. The difference is that its somewhat locked in to the containing class. you can access it from outside the class by preceding it with the class name. in your example like this:
 EnemyClass.CommonImage = LoadImage(file)

or with the instance of of the class:
local enemy:EnemyClass = New EnemyClass
enemy.CommonImage = LoadImage(file)

But within the class, you don't need to add the prefix to it and no matter how many times you create an instance of the Class, the global will keep it's single instance.
the Globals and Const are the only ones you don't need to create an instance of them to have access to them from outside the Class, from Methods and/or functions.

In your example every time you call the function to "LoadOneImage", it will store the image in the same Global variable "CommonImage". if you call it more than once from different instances of the class, the image will just be replace by the image last loaded.