an object lesson in classes “or how oo abl solves everything.”
TRANSCRIPT
AN OBJECT LESSON IN CLASSES
“or how OO ABL solves everything.”
BRIEF INTRODUCTION
• Julian Lyndon-Smith, IT Director dot.r limited• Progress developer since v3, 1987• Living proof of “old dog, new tricks”
• Often hanging around on PEG and PSDN• Always up for a good argument ;)
AGENDA
• Who’s afraid of the big bad wOOlf ?• Basics• Getting rid of the garbage• Inheritance, interfaces and all that• Advanced OO• Gotchas• Real world code ... Warts and all …
WHO’S AFRAID OF THE BIG BAD WOOLF ?• Survey : Progress version• <10.2B• 10.2B• 11.0• 11.1• 11.2
WHO’S AFRAID OF THE BIG BAD WOOLF ?• Survey : Who’s using OO• Not yet• Dabbling• Sometimes• Mostly• Wizard
BASICS : OO ADVANTAGES
• Type-safe• Cannot tipe a bad metgod name
• Encapsulation• Group together methods and data
• Code reuse
BASICS : OO ADVANTAGES
• Code completion• Makes you really cool• Talking about the fancy OO terms like “injection” ,
“factory”, “instantiation”, “inheritance” allows you to hang out with the cool kids
BASICS
• A class is an 4gl file with a .cls extension• Compiles to .r• Two parts: package and class name• Package is the directory where source lives• foo.bar.MyClass is foo/bar/MyClass.cls
• Using statement
BASICS
• An instance is a running class• Similar to persistent procedures• Run foo.p persistent set x • x = new foo().
BASICS : CREATE AN INSTANCE• /** foo/bar/MyClass.cls */
class foo.bar.MyClass:• end class.
• def var oFoo as foo.bar.MyClass no-undo.
• oFoo = new foo.bar.MyClass().
BASICS: PROPERTIES
• A property can be described as a procedure-wide “variable”• Extra toys to play with : get / set etc• Public and private
BASICS : PROPERTIES• /** foo/bar/MyClass.cls */
class foo.bar.MyClass:
• def public property guid as char no-undo get . set .
• end class.
• def var oFoo as foo.bar.MyClass no-undo.
• oFoo = new foo.bar.MyClass().
• Message oFoo:guid view-as alert-box.
BASICS: PROPERTIES
• Def [public | protected | private]• [public | protected | private] get.• [public | protected | private] set.
BASICS: METHODS
• A method can be described as a function• Without having to forward declare it• Returns a value or void• Can optionally have parameters
BASICS : METHODS• /** foo/bar/MyClass.cls */
class foo.bar.MyClass:
• method public void DoStuff():
• /** do some stuff */
• end method.
• end class.
• def var oFoo as foo.bar.MyClass no-undo.
• oFoo = new foo.bar.MyClass().
• oFoo:DoStuff().
BASICS : METHODS• /** foo/bar/MyClass.cls */
class foo.bar.MyClass:
• method public void DoStuff(p_name as char):
• /** do some stuff */
• Message p_name view-as alert-box.
• end method.
• end class.
• def var oFoo as foo.bar.MyClass no-undo.
• oFoo = new foo.bar.MyClass().
• oFoo:DoStuff(“my_little_pony”).
BASICS: METHODS
• Method [public | protected | private]
GETTING RID OF THE GARBAGE
• Persistent procedures can create memory leaks• Run foo.p persistent set x.• Must remember to delete x or memory leaks
• Classes have an automatic Garbage collector• Automatically deletes unreferenced class instances• You have no control over this
GETTING RID OF THE GARBAGE
• run DoMyStuff in this-procedure.
• /** do some more things like UI */
• procedure DoMyStuyff:• def var oFoo as foo.bar.MyClass no-undo.
• oFoo = new foo.bar.MyClass().
• oFoo:DoStuff().
• end procedure.
NOT GETTING RID OF THE GARBAGE• def var oFoo as foo.bar.MyClass no-undo.
• run DoMyStuff in this-procedure.
• /** do some more things like UI */
• procedure DoMyStuyff:• oFoo = new foo.bar.MyClass().
• oFoo:DoStuff().
• end procedure.
INHERITANCE, INTERFACES AND ALL THAT
• Inheritance • Interfaces• Polymorphism• Abstracts
INHERITANCE
• Abstract out common functionality (and data) from similar classes• A sub-class inherits from a super-class• A sub-class can extend or change behavior of super-class• Overriding methods• Adding new methods / properties
INTERFACES
• Specifies a set of method prototypes and properties • Similar to inheritance• No default implementation methods or properties
• Allows you to build different classes that conform to an API• Each class that uses an Interface must implement all methods and properties
defined in the interface
• Convention is that interface files start with an I
POLYMORPHISM
• As shown previously, multiple classes can inherit from same super-class• Sub-classes can override methods or behavior in the super-class• Multiple implementations (different parameters)• Different behavior : Same method, multiple signatures
• Super:Method()
ABSTRACTS
• Abstracts are classes than cannot be instantiated by themselves• Need to inherit an abstract class• All appropriate properties and methods are
available to sub-class
ADVANCED OO
• Events• Chaining• Parameter passing• Statics
ADVANCED OO : EVENTS
• Classes can raise “named” events• Define• Listen• Raise
ADVANCED OO : EVENTS• def public event StateChanged signature void (p_msg as char).
• StateChanged:publish(“foo”).
ADVANCED OO : EVENTS
• Def var oMessage as foo.Message no-undo.
• oMessage = new foo.Message().
• oMessage:StateChanged:Subscribe(this-object:StateChanged).
• /** do stuff */
• Method public void StateChanged(p_state as char):
• message p_state view-as alert-box info.
• End method.
ADVANCED OO : CHAINING
• Also called • Fluent-style coding• Fluent-coding style
•Methods return an instance of a class which is then used to call another method• Confused ?
ADVANCED OO : CHAINING• Association(BelongsTo("State"):Keys("StateID","State"):CascadeNullify()).
•
• Assocation(p_prop as dotr.property)• dotr.property – method BelongsTo [dotr.property] (p_name)• dotr.property – method Keys [dotr.property] (p_key1,p_key2)• dotr.property – method CascadeNullify()
• Association(BelongsTo("State")
:Keys("StateID","State"):CascadeNullify()
).
•
ADVANCED OO : CHAINING
• (new foo.bar()):DoStuff(). **• No need for variable• Does stuff• Gets GC’d automatically
• ** new foo.bar():DoStuff(). • Hopefully in 11.3
ADVANCED OO : PARAMETER PASSING
• Parameters : pita• Change over time• Need to write new ip’s to handle new parameters• May need to revisit old code and change
ADVANCED OO : PARAMETER PASSING
• Use an instance of a class as a Parameters• Change properties of class• All inputs now have additional properties without changing
a line of code
• Input == input-output
ADVANCED OO : STATICS
• A static method is loaded into memory. Once.• Can then use that method without having to define a
variable• Foo.bar()• Foo is the class, bar is a static method
ADVANCED OO : STATICS
• Tempting to use• Cannot be unloaded at all from session• Do not use record buffers in any method of a class that
has a static member• Buffers are then “locked” into memory• Impossible to update db whilst app is running
GOTCHAS
• Event Subscription• Potentially no garbage collection
• Sockets• AppServer boundaries• No serialization
GOTCHAS
• Statics•OO-guys can sound more intelligent than you• Doing stuff in the constructor
SHOW ME THE CODE
• Demos and walkthroughs of the various technqiues • perhaps even “on demand coding”
QUESTIONS,DEBATE