2 single: Object Oriented Programming; Introduction
4 =================================
5 Object Oriented Programming (OOP)
6 =================================
8 In this chapter we are going to learn how to use the Object-Oriented programming paradigm
9 inside the Ring programming language.
14 * Access Objects Using Braces
17 * Private Attributes and Methods
18 * Operator Overloading
23 * Find() and List of Objects
24 * Sort() and List of Objects
25 * Using Self.Attribute and Self.Method()
26 * Using This.Attribute and This.Method()
30 pair: Object Oriented Programming; Classes and Objects
36 We can define new classes using the next syntax
42 Class <Class Name> [From|<|: <Parent Class Name>]
50 And we can create objects using the next syntax
56 New <Object Name> [ (init method parameters) ] |
57 [ { access object data and methods } ] ---> Object
63 New point { x=10 y=20 z=30 print() }
64 Class Point x y z func print see x + nl + y + nl + z + nl
66 .. note:: We can use { } to access object data and methods.
68 .. tip:: we can declare the class attributes directly after the class name.
78 We can rewrite the same program in another style
82 New point # create new object using the point class
83 { # access the new object attributes and methods
84 x = 10 # set the x attribute to 10
85 y = 20 # set the y attribute to 20
86 z = 30 # set the z attribute to 30
87 print() # call the print method
88 } # end of object access
91 Class Point # define the Point class
92 x y z # the class contains three attributes x, y & z
93 func print # define the print method
94 see x + nl + # print the x attribute
95 y + nl + # print the y attribute
96 z + nl # print the z attribute
100 Also we can write the same program in another way
109 Class Point x y z func print see x + nl + y + nl + z + nl
111 .. note:: we can use the dot operator after the object name to access object members.
113 Also we can write the same program in another way
117 new point { print() }
120 func print see x + nl + y + nl + z + nl
122 .. note:: we can set the default values for the class attributes when we declare them.
124 Also we can write the same program in another way
131 func init p1,p2,p3 x=p1 y=p2 z=p3 print()
132 func print see x + nl + y + nl + z + nl
134 .. note:: we can call the init method directly using () when we create new objects
136 Also we can write the same program in another way
140 new point( [ :x = 10 , :y = 20 , :z = 30 ] )
142 func init aPara x = aPara[:x] y = aPara[:y] z = aPara[:z] print()
143 func print see x + nl + y + nl + z + nl
145 .. tip:: using Hash for passing method parameters enable us to create optional
146 parameters and change the order of parameters when adding them to the Hash.
149 pair: Object Oriented Programming; Access Objects Using Braces
151 Access Objects Using Braces
152 ===========================
154 We can access the object at any time using braces { }
156 Inside the braces we can use the object attributes and methods directly
158 This can be done when we create the object using the New keyword or at any time using the next syntax
162 ObjectName { access object data and methods }
168 See "Creating the Object" + nl
170 See "Using the Object" + nl
177 Class Point x y z func print see x + nl + y + nl + z
179 We can use braces to access objects when we call functions or methods
187 print( o1 { x=10 y=20 z=30 } )
196 We can mix between using braces and the dot operator to access the object in the same expression.
205 O1 { x=10 y=20 z=30 }.print()
208 func print see x + nl + y + nl + z
211 pair: Object Oriented Programming; Composition
216 The object may contains other objects as attributes.
218 Using braces to access objects can be nested.
245 see "Name : " + R1.Name + nl +
246 "Color: " + R1.Color + nl +
247 "P1 : (" + R1.P1.X + "," + R1.P1.Y + ")" + nl +
248 "P2 : (" + R1.P2.X + "," + R1.P2.Y + ")"
267 pair: Object Oriented Programming; Setter and Getter
272 We can define methods to be used when we set and get object attributes.
283 Func SetAttributeName
286 Func GetAttributeName
295 o1.name = "Mahmoud" see o1.name + nl
297 o1 { name = "Ahmed" see name }
301 name family = "Fayed"
304 see "Message from SetName() Function!" + nl
305 name = value + " " + family
308 see "Message from GetName() Function!" + nl
315 Message from SetName() Function!
316 Message from GetName() Function!
318 Message from SetName() Function!
319 Message from GetName() Function!
323 pair: Object Oriented Programming; Private Attributes and Methods
325 Private Attributes and Methods
326 ==============================
328 We can define private attributes and methods after the keyword private inside the class body
348 o1.increasesalary(1000)
358 see "Name : " + name + nl +
362 see "Salary : " + salary + nl
368 func increasesalary x
378 Error (R27) : Using private attribute from outside the class : salary
379 Error (R26) : Calling private method from outside the class : increasesalary
382 pair: Object Oriented Programming; Operator Overloading
387 We can add the operator method to our class to enable using operators with the class objects.
397 Func operator cOperator,Para
401 The function operator takes two paramters, the first represent the operator
402 and the second represent the second parameter after the operator.
408 o1 = new point { x = 10 y = 10 print("P1 : ") }
409 o2 = new point { x = 20 y = 40 print("P2 : ") }
416 func operator cOperator,Para
420 result.x = x + Para.x
421 result.y = y + Para.y
423 result.x = x - Para.x
424 result.y = y - Para.y
429 see cPoint + "X : " + x + " Y : " + y + nl
437 P1+P2 : X : 30 Y : 50
440 The next example from the List class in the stdlib.ring
444 Func operator cOperator,Para
464 The "len" operator is used with (for in) control structure.
466 The "[]" operator is used when we try to access the list items, In this case we use the & operator
467 to return the item values like strings an numbers by reference, so we can update it when we access the
477 a1 = new BigNumber( "123" )
478 a2 = new BigNumber( "456" )
479 a3 = new BigNumber( "789" )
494 ###==================================
495 Func FuncAdd( num1, num2)
496 Sum = 0 + num1 + num2 ### Para.aData isNumber
497 Sum = "" +Sum ### Para.adata isString
498 return Sum ### return to Class
499 ###===================================
506 ### Functions INIT default values
508 ? "INIT aPara: " ? aPara
516 func operator cOperator, Para
517 whatType = Type(Para)
518 ? nl+"WhatType-PARA: "+ whatType ? Para
519 ? nl+"Operator: " ? cOperator ? nl+"PARA: " ? Para ? " ______" ? nl
520 if whatType = "STRING"
522 ? "dataInfo String: " ? dataInfo
523 but whatType = "NUMBER"
525 ? "dataInfo Number: " ? dataInfo
526 else whatType = "OBJECT"
527 dataInfo = "" + para.aData
528 ? "dataInfo OBJECT: " ? dataInfo
530 ? "dataInfo USING: " ? dataInfo
531 ### Para.aData does NOT exist on first pass ( Object with member)
532 ### Result isObject when assigned "self"
536 answer = FuncAdd( aData, dataInfo )
537 ? nl+"AnswerString - FunAdd aData, dataInfo: " ? answer
538 ### result = self, is Object, populate Object with aData member
539 result.aData = answer
541 ### Result = Self is Object
545 ? nl+"ClassPrint aData: " ? aData
548 pair: Object Oriented Programming; Inheritance
553 We can create class from another class in the class definition using the keyword from.
559 Class <Class Name> [From <Parent Class Name>]
561 We can call a method in the parent class from the child class using the super object.
589 see "Name : " + name + nl + "Age : " + age + nl
591 Class Employee from Human
595 see "Job : " + job + nl + "Salary : " + salary + nl
607 pair: Object Oriented Programming; Dynamic Attributes
612 We can write instructions after the class name to be executed when we create new objects
618 o1 = new dynamicClass
619 see o1.var5 + nl # output 5
623 cStr = "var" + x + " = " + x
627 .. tip:: in the previous example var1, var2, ..., var10 will be defined as attributes.
629 .. tip:: The problem with the previous example is that x and cStr will be defined as attributes too!
631 .. note:: we can write class definitions inside a string then
632 using eval() we can execute the string to define the classes
635 pair: Object Oriented Programming; Packages
640 We can create a package (a group of classes under a common name) using the next syntax
657 o1 = new System.output.console
658 o1.print("Hello World")
660 Package System.Output
665 .. note:: we can use the dot operator as part of the package name
667 Instead of typing the long name PackageName.ClassName we can use the import command
669 When we import a package, we can use any class inside this package directly.
679 Package System.Output
685 pair: Object Oriented Programming; Printing Objects
690 We can print the object state (attributes and values) using the see command.
696 see new point { x=10 y=20 z=30 }
708 pair: Object Oriented Programming; Find() and List of Objects
710 Find() and List of Objects
711 ==========================
713 We can use the find() function to search inside a list of objects.
719 Find(List,ItemValue,nColumn,cAttribute) ---> Item Index
725 myList1 = [new Company {position=3 name="Mahmoud" symbol="MHD"},
726 new Company {position=2 name="Bert" symbol="BRT"},
727 new Company {position=1 name="Ring" symbol="RNG"}
730 see find(mylist1,"Bert",1,"name") + nl
731 see find(mylist1,"Ring",1,"name") + nl
732 see find(mylist1,"Mahmoud",1,"name") + nl
733 see find(mylist1,"RNG",1,"symbol") + nl
734 see find(mylist1,"MHD",1,"symbol") + nl
735 see find(mylist1,"BRT",1,"symbol") + nl
736 see find(mylist1,3,1,"position") + nl
737 see find(mylist1,1,1,"position") + nl
739 see find(mylist1,"test",1,"name") + nl
740 see find(mylist1,"test",0,"name") + nl
741 see find(mylist1,"test",5,"name") + nl
743 class company position name symbol
763 pair: Object Oriented Programming; Sort() and List of Objects
765 Sort() and List of Objects
766 ==========================
768 We can sort a list of objects based on an object attribute using the Sort() function.
774 Sort(List,nColumn,cAttribute) ---> Sorted List based on Object Attribute
781 new Company {position=3 name="Mahmoud" symbol="MHD"},
782 new Company {position=2 name="Bert" symbol="BRT"},
783 new Company {position=8 name="Charlie" symbol="CHR"},
784 new Company {position=6 name="Easy" symbol="FEAS"},
785 new Company {position=7 name="Fox" symbol="EFOX"},
786 new Company {position=5 name="Dog" symbol="GDOG"},
787 new Company {position=4 name="George" symbol="DGRG"},
788 new Company {position=1 name="Ring" symbol="RNG"}
791 see sort(mylist1,1,"name")
792 see copy("*",70) + nl
793 see sort(mylist1,1,"symbol")
794 see copy("*",70) + nl
795 see sort(mylist1,1,"position")
797 class company position name symbol
828 **********************************************************************
853 **********************************************************************
880 pair: Object Oriented Programming; Using Self.Attribute
882 Using Self.Attribute and Self.Method()
883 ======================================
885 Inside the class region (After the class name and before any method) and the class methods we can
886 use self.attribute and self.method()
895 see self.x + nl + self.y + nl + self.z + nl
897 .. note:: using self.attribute in the class region to define the class attribute protect the class attributes from conflict with global variables.
899 .. tip:: if you typed the class attributes with self.attribute and there are a global variable with the same name it will be used and the attribute will not be defined.
901 Check the "Scope Rules" chapter to know about the conflict between the global variable name and the attribute name
903 Whay this may happens?
907 * Because in the class region we can access global variables.
908 * Before defining any variable, Ring try to find the variable and use it if it's found.
910 .. note:: Try to avoid the global variables, use the main function and start their names with $
912 .. tip:: In large programs protect your classes and define their members using self.attribute
915 pair: Object Oriented Programming; Using This.Attribute and This.Method()
917 Using This.Attribute and This.Method()
918 ======================================
920 Inside class methods we have access to the object scope directly. we don't need to use Self.attribute
921 or Self.method to read/write attribute and call methods.
923 But we can use braces {} while we are inside methods to access another object, In this case the current
924 object scope will be changed while we are inside the brace.
926 How we can get access to our class attributes and methods while we are inside braces?
928 This can be done using This.Attribute and This.Method()
941 display(this.x,this.y,this.z)
946 see x + nl + y + nl + z + nl
949 pair: Object Oriented Programming; Using This in the class region as Self
951 Using This in the class region as Self
952 ======================================
954 The class region is the region that comes after the class name and before any method.
956 We can use This in the class region as Self.
972 this.name = "My Application"
978 ? "Version = " + version
986 Name = My Application
991 .. note:: When we use braces to change the current active object, Using This we can still point to the class.
993 .. tip:: The difference between This and Self is that Self point to the current active object that we can change using braces.
995 Remember that in most cases we don't need to use This or Self in the class region
1000 .. code-block:: ring
1002 class program name version
1006 .. code-block:: ring
1008 class program name="My Application" version="1.0"
1010 .. note:: We use This or Self in the class region just to avoid conflict with global variables that are defined with the same name.
1014 pair: Object Oriented Programming; Default value for object attributes
1016 Default value for object attributes
1017 ===================================
1019 The default value for object attributes is NULL
1021 In Ring, the NULL value is just an empty string or a string that contains "NULL"
1023 We can check for NULL values using the isNULL() function
1027 .. code-block:: ring
1029 oProgram = new Program
1032 ? isNULL(oProgram.name)
1033 ? isNULL(oProgram.version)
1034 oProgram { name="My Application" version="1.0" }
1035 ? isNULL(oProgram.name)
1036 ? isNULL(oProgram.version)
1045 .. code-block:: none
1053 name: My Application