A Dirty Guide to OOP #1
Posted
#1
(In Topic #372)
Regular

OOP is all about identifying aspects of your project that can be implemented as objects. An object is usually a noun (e.g. fruit, animal, machine) with Properties (e.g. colour) Methods (e.g. delete) and sometimes Events (e.g. LostFocus).
Although "Class" in general programming can mean just a bunch of code in a module, in OOP a Class is the code you write as a kind of template from which you create Objects.
So here is a simple "fruit" example; Start a new project and then right-click in the Project window and select New > Class… and name it "clsFruit.class".
Another principle of OOP is encapsulation. We usually hide the internal class properties from the outside world and use "Getter" functions & "Setter" functions to read & write them. So even in our simple example, we need to Declare in the clsFruit.class any properties that we want to make available. Initially we need a Property called "Name" and another called "Colour" :-
…then we create Private properties:-
…then we create Getter & Setter functions:-
At this stage our class doesn't do much, but we can use it.
On the main project form add this code to create a new instance of our class:-
Note: If autocomplete is working on your system, you should see the class name and properties listed as you type.
Now add a Button and add this as its click event:-
So you should now have a working example. You can create as many objects as you like from this new class, for example:-
…and each instance can be given its own unique name & colour.
If this is of interest to anyone, I'm happy to write more.
Posted
Administrator

stevedee said
If this is of interest to anyone, I'm happy to write more.
Yes. I have no formal training in programming so I enjoy reading these short "lessons with examples" (the same with your personal website).
Posted
Enthusiast

Posted
Regular

Looking at the 'Fruit' example, you may wonder if its really worth the trouble. But one of the central principles of software development is "code re-use". If someone is paying you to write code, they don't want you to keep writing the same or similar stuff. Not only is this time consuming, but its also detrimental to code quality.
So whenever you find a use for some function more than just once or twice, the code should be written into a Module (I think Gambas calls this a static class). And if the task lends itself to becoming an Object, then write this code as a Class (I think Gambas calls this a creatable class).
Also, imagine that we expand our fruit class to have properties & methods for taste, size, position, visibility & so on, and we use it in a crazy fruit game where 100's of pieces of fruit are created and destroyed. If you didn't use objects, your code would probably be huge!
Anyway, I want to expand our fruit class by including a read-only property. All fruits have a skin, so lets add a boolean called HasSkin:-
Code (gambas)
Notice that we use "Read" to declare the property and we don't included a setter. But we do need to set this property to True by default:-
And now in the main form, we add some code to check if our fruit has a skin:-
Once you remove the skin from fruit, there is no going back. So here is a simple Method called Peel:-
…and updated main form code:-
Posted
Regular

For most simple, non-graphical objects that you write, you may only need to implement Properties and Methods as described in the 2 earlier parts of this guide. (Take a look at my Wireless-range project which includes 2 class/objects: Gambas One - Gambas ONE)
But another aspect of the OOP paradigm which we should consider is "inheritance", which continues the "code re-use" idea by allowing one object to form the starting point for another. For Properties in particular, this means that the same names & meanings are maintained for many objects. Which makes it easier for us programmers, as we have less to remember.
For example, most of the Gambas visual components inherit from the Control class/object. So many properties (such as Name, Text, Enabled, Background, Width & so on) are the same for all descendants of Control, and quickly gain familiarity with those new to the language.
However, routine use of Inheritance in your written code can easily get out of hand. An object with too many ancestors will quickly accumulate a lot of Properties & Methods, and can make the code very difficult to read & understand (…I'm thinking of my time with C++).
Gambas allows you to use a maximum of (I think) 16 generations or levels of Inheritance, which in my opinion is about 15 too many! (…yes, this is the Dirty part of my simple guide).
Anyway, let's give simple inheritance a go!
Start a new project for vegetables, and copy the clsFruit.class file to the new project's .src folder. Add a new class called clsVeggie.class.
In clsVeggie write "Class clsVeggie Inherits clsFruit" and then create a boolean Property the OOP way, called RootVeg:-
In the Form class of this new project, create a new instance of clsVeggie and then add some trivial code to test it. Maybe some nonsense like this:-
Code (gambas)
- myVeg.Name = "veg-edible"
- myVeg.Colour = "Red"
- WhichVeg
- WhichVeg
Note: Although this example demonstrates the principle that the new clsVeggie has inherited the basic Properties & Methods from clsFruit, there are a few points to note:-
1) autocomplete did not work for me when typing in lines like myVeg.Name (maybe that is a limitation of the IDE)
2)The format for Inherits is: Class <this-class>Inherits<ancestor-class>
I found that simply: Inherits<ancestor-class> also works at the time of writing, however its probably safer to use the full version, as the format could be tightened up in subsequent releases without notice.
3) my example may not show the correct way to implement inheritance…who knows? I haven't been able to find an example of how to do this…so if you have a better example, please post it here.
Posted
Regular

There may be times when you want your Object to raise Events, especially if your program is for a computer with switches or sensors attached to its inputs.
Returning to our Fruit class example, I'm going to add a "rotten fruit" Event.
In clsFruit, add a line to declare the Event, a timestamp in the class constructor, and a new Method called "sniff". The complete class code should now look like this:-
Code (gambas)
In the Form class, add a third Button, change the object Declaration line to include a local name for the Event, and a routine to run when the event is triggered:-
Code (gambas)
- myApple.Name = "apple"
- myApple.Colour = "red"
- myApple.Peel
- myApple.Sniff
When you run this code, sniffing the fruit by clicking Button3 is not a problem until the life of the fruit is exceeded.
So what's happening here is that:-
1)The Event called "Rotten" is declared in our object/class
2)An Object is Declared and Instantiated in our form code which includes a local name for the Class Event (you can call it anything)
3)The Event routine in our form is referenced by our 'local event name'_'Class event name' (i.e. FruitEvent_Rotten)
4)When the "Raise" keyword is executed in our Object, the FruitEvent_Rotten routine is called and the string containing the message is passed as an argument.
Posted
Regular

Like the guide so far. BTW, the syntax you may need probably looks like…
…because that's how I got my Dock and Anchor classes to inherit from DockAnchorBase in my DockAnchor library.
SteveS
https://github.com/ssepan2/DockAnchor
_______________
stevedee said
A Dirty Guide to OOP #3
Note: Although this example demonstrates the principle that the new clsVeggie has inherited the basic Properties & Methods from clsFruit, there are a few points to note:-
1) autocomplete did not work for me when typing in lines like myVeg.Name (maybe that is a limitation of the IDE)
2)The format for Inherits is supposed to be:-
MissingAs.png
…but I couldn't get this to compile.
3) my example may not show the correct way to implement inheritance…who knows? I haven't been able to find an example of how to do this…so if you have a better example, please post it here.
Posted
Regular

I'm not sure I have much more to add on the subject of OOP. I did a search yesterday for polymorphism & Gambas, but didn't find anything useful.sjsepan said
Like the guide so far….
Maybe we can get the views of forum members on whether they use OOP in their programs, or whether they even like it (not everyone is a fan).
I like to create objects when I spot a suitable candidate in a project. I generally avoid using Inheritance between/within classes that I've written.
And I used to avoid putting code in a Form class that had nothing to do with the form (e.g. 'F to 'C conversion function would go in a Module, if it couldn't be part of an object) …sadly, most of my recent stuff is just a hack (…a hack is where you just sit at your keyboard and type code, with little or no pre-planning!)
Thanks Steve, I have now updated the post with this syntax.BTW, the syntax you may need probably looks like…
I tried to download your project but it is missing the library: GambasAppUtilityLib …which I think you will find in your:…because that's how I got my Dock and Anchor classes to inherit from DockAnchorBase in my DockAnchor library.
/usr/lib/Gambas3/stephensepan directory
Posted
Guru

The challenge was set so I came up with:-
<IMG src="http://www.cogier.com/gambas/Forms.png">
</IMG>Now to the 'OOPS' part: -
I decided to try and make the 'Button' used into a class and with the help of my friend Matt came up with this. Once you get the hang of this it is extremely powerful as you are able to add Properties to the IDE. You can see 'EnterColor' and 'FlashColor', amongst others, in the image below. The Form below has been created entirely in the IDE and only 3 lines of code, outside ButtonPlus.class is used.
<IMG src="http://www.cogier.com/gambas/ButtonPlus.png">
</IMG>I have used 'ButtonPlus' in Remember in Project Showcase. if you want to try it just 'Import' the class into a new 'Graphical Application' and run the program. You will then find 'ButtonPlus' available in the Form toolbox, see image above. The 'ButtonPlus' is designed to work like RadioButtons. Click one and the others reset.
Posted
Regular

Thanks Steve, I have now updated the post with this syntax.BTW, the syntax you may need probably looks like…
I tried to download your project but it is missing the library: GambasAppUtilityLib …which I think you will find in your:
/usr/lib/Gambas3/stephensepan directory
That project is also out on github (https://github.com/ssepan2/GambasAppUtilityLib); I've not uploaded the latest versions to the GambasFarm because I was getting errors uploading library projects.
Steve S
Posted
Trainee
Say, I have a resultset with two fields: id, oName
Can I create a class?
Public id as integer
public oName as string
public sub set_delete() –go delete
public sub set_by_id($id as integer) – go populate obj
public sub set_insert() – go insert
etc..
Posted
Guru

I was wondering if it is at all possible to create objects at runtime.
Run this in a new 'Graphical application'
Code (gambas)
- .Text = "Hello salihburhan"
- .Width = 300
- .Height = 56
- .X = 50
- .Y = 10
- .Text = "&Click me!"
- .Height = 28
- .Width = 98
- .X = 50
- .Y = 70
- Label1.Text = "From cogier"
- Label1.Text = "Hello salihburhan"
Grab the code from here and run it in the same way to see what can be done.
Does that help?
Posted
Regular

salihburhan said
…Can I create a class?…
Cogier's example shows creating objects from classes, but I don't believe that it is possible to create a class at runtime, if that is what you are asking.
Languages like VB.Net have a CreateClass command, but I don't think Gambas has an equivalent.
Posted
Regular

Just funning.
Writing code generators is fairly straightforward. Given a list of fields and their types, there is certainly a formula for codifying that as a Gambas Class file.
Thus, one could write a program that reads the specs for class definition, writes the class definition as source code (along with a testing program), compiles the code, then shells out to run the compiled code.
Technically, it's the same thread executing the code it generated.
.... and carry a big stick!
Posted
Regular

Cedron said
…Writing code generators is fairly straightforward. Given a list of fields and their types, there is certainly a formula for codifying that as a Gambas Class file….
Hey that sounds interesting. Can you give us a simple code example?
Posted
Trainee
So maybe it might be possible to pass along a string to be compiled and a name for the class.
It can return a variable that has standard methods.
$var.insert()
$var.update_name()
Other than databases that host frameworks (like wordpress), would there be any other application?
Posted
Guru

Hey that sounds interesting. Can you give us a simple code example?
This got me thinking and I came up with the attached program. This program will create a new folder and all the normal Gambas files and folders. It will add the code to FMain.class and then compile, make an executable and run it, all nearly instantly. You can add some text to the new program which will be displayed at the bottom of the Form.
I'm not sure this is exactly what people were looking for but here it is anyway.
<IMG src="http://www.cogier.com/gambas/CreateCode.png">
</IMG>
Posted
Guru

As of Gambas 3.14 the "Use" keyword was introduced to save on code.
So before you would write..
Now you can simply write…
This saves a lot of code but take note..
It will make your application fail if run on a gambas version less than 3.14 so if you want to share your app with debian users who might still be using Gambas 3.12 then do not use it.
Posted
Regular

1 guest and 0 members have just viewed this.

