Classes, method or any thing to do with classes
Monkey Archive Forums/Monkey Tutorials/Classes, method or any thing to do with classes
| ||
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. |
| ||
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.... |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 :) |
| ||
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? |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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 !! |
| ||
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. |