Class/Interface/Contract -- Re: fake class in OE
- Posted by irv Feb 23, 2021
- 1180 views
To expand on that (Pete will correct me if I'm wrong):
With Phix, a class can have public, or private, properties.
When you declare a property as public, it acts just like any other variable, except that it is "owned" by the class instance. Types work the same as they do elsewhere, but with an added feature (we get to that later).
class Cow public integer horns; end class Cow bossie = new() ? bossie -- {"struct","Cow",4,1} instance 1 of class Cow Cow bessie = new() ? bessie -- {"struct","Cow",4,2} instance 2 of class Cow bessie.horns = 2 bossie.horns = 0 ? bessie.horns -- prints 2
If you declare a property as private, Phix looks for a routine of the same name, prepended by "set_" or "get_".
class Cow private integer horns; procedure set_horns(integer n) -- we have a chance to do something in addition to just setting the number of horns if n < 0 or n > 2 then ?"You're kidding, right?" -- made up example; else this.horns = n end if end procedure function get_horns() -- maybe do something here (beep once for each horn?) return this.horns end function end class ? bossie.horns -- automatically calls function get_horns() for the bossie instance bessie.horns = 3 -- automatically calls procedure set_horns() for the bessie instance
Properties aren't limited to the normal types (integer, bool, atom, string, sequence, or user-written types), they can also be declared as being a class type. For example, think of a Dialog window, which pops up a message.
It will have, at the least, a label with some text, a button or two, and perhaps an Icon: So you will have written a Button class, an Image class, and a Label class. Then the Dialog might have either public or private properties of those types:
include Image.e -- exports declaration and code for class Image; class Dialog private Image icon; procedure set_icon(Image i) -- will only accept an instance of Image class; ? i -- {"struct","Image",6,1} <-- this is the instance passed to set_icon() -- do something with that image (resize it, perhaps?) this.icon = i -- then update the dialog's icon, probably by calling a c_proc() In GTK, it would look something like: c_proc(define_c_proc(GTK,"gtk_dialog_set_image",{C_POINTER,C_POINTER}),{this.handle,i.handle}) end procedure end class Dialog d = new() Image x = new({"mongoose.jpg"}) d.icon = x -- calls the set_icon() function for class Dialog ,instance d, passing the Image structure;
Of course, a Dialog is a kind of Window, so they share some of the same properties, for example, size. Rather than write and debug a set_size() function for every object that has a size property, it's better to do that just once:
include Window.e -- exports declaration and code for class Window -- the Window class declares a private sequence size; include Image.e class Dialog extends Window -- inherit properties and code from Window (can inherit from more than one class) private Image icon; procedure set_icon(Image i) this.icon = i -- update the dialog's icon end procedure end class Dialog d = new() d.size = {300,400} -- calls the set_size() function in the Window class Image x = new({"mongoose.jpg"}) d.icon = x
Now, anything that derives from a Window automatically has the ability to set or get its size.