REALbasic University Resources:

RBU: Glossary Defines common REALbasic programming terms
  Archives Previously published columns
Translations: Dutch Courtesy of Floris van Sandwijk
  Japanese Courtesy of Kazuo Ishizuka
  Chinese Courtesy of Dong Li
  RBU Translation Guide Information on Translating RBU into other languages
Books: Matt's Book (2nd Edition!) Ideal for experienced programmers
  Erick's Book Best for beginning programmers
Websites: Mother Ship The publisher of REALbasic
  RB Webring Links to hundreds of REALbasic websites
  RESExcellence Another REALbasic programming column
  REALbasic Developer Magazine The premiere source for REALbasic instruction.

REALbasic University is Sponsored by

Make your Mac do what YOU want it to. Create games, utilities, cool Mac OS X tricks. Download REALbasic now and create your own software.


Print This Article

REALbasic University: Column 080

OOP University: Part Four

Last time I explained what objects are. Today we're going to look at a key distinction about objects which is rarely discussed. I'm going to do this by explaining the importance of naming classes and objects clearly.

The Importance of Names

Because of their ability to interherit characteristics, a structure of classes can quickly become enormously complex. (Even our little table of cats is getting complicated!) You have parent classes, children, and grandchildren, each with unique characteristics. Once you start generating instances of the various classes (i.e. mischiefInstance and mayhemInstance in the above), it is easy to confuse yourself.

Especially as a beginning OOP student, it is vital that you name your classes and objects in a consistent and logical manner. Drastic problems can come from confusing classes and objects.

For example, let's look at this class definition and object use:

  
Class TVobject
dim on as boolean
dim channel as integer
dim pip as boolean
dim screensize as integer
end Class

sub action
dim myTV as TVobject

myTV = new TVobject
myTV.screensize = 32
myTV.pip = true
myTV.on = true
myTV.channel = 823
...
end action

Right away, I sense a horrible problem. By naming this class "TVobject," you've just confused yourself. "TVobject" is not an object: it's a class (a structure, definition, or description, depending on how you want to look at it). There's a huge difference (which I'll explain in more detail in the next lesson). You're basically confusing blueprints with the building! (Class = blueprint, object = building).

A class defines the structure of an object, but it is not an object itself. A much better way is to define things like this:

  
Class tvClass
dim on as boolean
dim channel as integer
dim pip as boolean
dim screensize as integer
end Class

sub action
dim myTVInstance as tvClass

myTVInstance = new tvClass
myTVInstance.screensize = 32
myTVInstance.pip = true
myTVInstance.on = true
myTVInstance.channel = 823
...
end action

I like to use the word "class" in my class definitions just to remind me that it's a class, not an object. For the purposes of this tutorial series, I also use "instance" as part of any object instance. Generally your objects will seem like objects to you and that's not strictly necessary, but if you're just starting to work with objects, it's important to maintain the distinction and get it stuck in your head.

What's an instance, you ask? Well, that's a little complicated to get into today: we'll tackle that in the next lesson.

Next Week

We dive into the prickly topic of instances.

Letters

Here's a letter from Thomas Ferrell with a good question about the difference between App and Module:

Hi,

A particularly puzzling aspect of RB to me is the inclusion of an App and a Module. I have learned you can store globals in a Module, that an App is needed for AppleScript basic compliance (& for menus, although it's not clear which belong in an App and which belong in a window), but surely there should be something that gives guidance to the overall structure of a program and that tells you about what should be added what and what is necessary. What is an App anyhow---I thought all programs were Apps? A flowchart would be helpful, but a few examples with documentation/explanation wouldn't hurt. The RB Developer's Guide has a Chapter on Modules, but a brief couple of paragraphs are warranted that show where problems might occur with functions defined elsewhere and the idea of a module should be integrated into an introduction to overall program structure.

Cheers,
Tom

An excellent question, Tom! Fortunately, it's easily explained.

A module is a collection of code. It can contain constants, methods, and properties. All are global: that is, they are available to every other part of your program.

The idea of a module is that it should contain routines that are reusable in other programs. For instance, I have a "prefsModule" that contains the basics for the system I use for loading, parsing, and saving preference options. I install this in a program and then I can easily customize it for that specific app.

You can export a module by dragging it to a Finder window (REALbasic will create a file with the module's data in it). You can import that module into another program by dragging the module file from the Finder to the current Project window.

REALbasic University Quick Tip

If you hold down the Option and Command keys as you drag the module file into your project, REALbasic won't copy the module but will link to it. That means you can't delete the original module file from your hard drive, but it also means that multiple programs can use the same module. Therefore if you fix a bug in the module or improve it some way, all the other programs that use that module will benefit!

Now the "App" thing is a lot more confusing.

In Detail

If you aren't familiar with the "app" class object, you add it to your project like this:

Choose "New Class" from the file menu.

Select the Class1 item inserted in your project window and rename it app on the Properties window.

On the Properties window, make app's Super "Application" (you can type it or select it from the list).

Once you've done this, you can use the app class you just created to access special application events (see more below).

Technically, app is a subclass of the Application class. The reason you subclass it is that you can therefore make changes to it (i.e. add properties, events, methods, etc.).

By default, all REALbasic applications automatically have an Application object. It's just that you don't see it (there's no interface to it). I think it would be simpler and clearer if REAL Software made it so all new projects included an app class by default. Having it there unused wouldn't hurt anything, but it'd be there when you needed it instead of having to add it manually.

Since you can't see the included-by-default Application object, you can't change it. By adding your own subclass, you're free to expand upon the limited capabilities of the normal Application class object.

You are correct when you mention that you need to add an app class when you want to handle Apple Events (AppleScripts communicate via Apple Events). There are other benefits as well:

  • Activate/Deactive events
  • EnableMenuItems event
  • HandleAppleEvent event
  • NewDocument event
  • OpenDocument event
  • UnhandledException event

The HandleAppleEvent event is where you parse any Apple Events sent to your program. NewDocument and OpenDocument is where you should put code that is executed when the user tries to create a new document or open an existing document. UnhandledException is for handling exception errors that aren't caught elsewhere in your program.

You mention being confused by the fact that App has it's own menu handling system. In truth there's a simple explanation. Normally you put most menu handlers within a window, right? That's because most documents are a window and in true object-oriented design you want the document object (the document window) to handle the menu commands associated with documents.

But what if all the windows are closed? If the only place you handle menus is within window objects, there'd be no way for the user to use any menus with all the windows closed!

Fortunately, the main command you'd want to use when the windows are closed -- "Quit" -- is handled automatically by REALbasic. So at least the user can quit your program without you doing anything specific to support that. But what about stuff like creating a new file, opening an existing file, or setting preferences? Those might be things a user would like to do without having a document already open.

Depending on your application, you might even want to have different preferences for when there's no document open (application preferences) and document-specific settings (document preferences). To illustrate this, I've created a demonstration REALbasic project which you can explore (appdemo.sit). Note that it functions just for display purposes only: no preferences are actually remembered.

Here's a flowchart that maps how this application works:

You see, the window menu handlers have first priority. So if there's a window open, the window's filePreferences menu handler is executed. Since menu handlers return false by default, we've got to return true within that handler or else app will also handle the menu event:

In the demo program, try commenting out the return true line above and see what happens!

If your window doesn't handle the menu event (or there are no open windows), REALbasic passes the event on to your application object (an instance of your app class, if you created one) and lets it handle it (if it can). This allows you to display one preference dialog for documents (local), and a different one for application settings (global).

Note that some menu commands are inappropriate to handle within the application object: the "Close window" command, for instance. If you tried to handle it within the application object, you'd have to first check to see if there are open windows, and second you'd have to figure out which window was the one the user wanted to close. By placing it within the window itself, we greatly simplify things. After all, if the window exists (which it must, for its code to be executed), we know there's at least one window open and the Close command is valid so we can just close the current window. If all the windows are closed, there are no docWindows to detect the Close menu command: the app object doesn't need to do anything (the Close menu command is disabled).

Just as the Close window menu handler is inappropriate to place within the app object, it would be silly to put the "new" and "open" handlers within a window. First, if you didn't have code within app and there are no open windows, there'd be no way to create or open a new document! Second, since you therefore must have code within app, why duplicate that menu handler code within a window?

Hopefully you can begin to see how these two system divide the workflow. Windows override the app, but app is there if no windows are open. Sometimes one or the other needs to handle the menu command, but there are occasions (such as the Preferences situation) when you want both to function but function slightly differently.

If different windows support different menu handlers, the handlers of the window in front (the active window) are the ones that are used.

In Detail

You might also remember that you can subclass controls and these new objects can have their own menu handlers. When a control has its own menu handler, it has priority over a window's menu handlers. So the order is:

  
control > window > app

The best way to understand this is with an example. See my "select all editField" class in saeditfield.sit to see how a subclass can use its own menu handlers.

You might realize that app's Activate and Deactivate events work the same as the menu handling system: if windows are open, those also have Activate and Deactivate events, but if none are open you'd have no way to detect program activation without the app object.

Really, the only thing that makes this confusing is that you sometimes create projects with an app class and you sometimes don't. Beginners can't figure out when they need it. In reality you almost always need it, and it doesn't hurt anything if it's there and not used, so why not always include it? Get in the habit of adding an app class to all your projects.

You can download appdemo.sit by clicking here.


About the Column
REALbasic University is a weekly instructional column on programming with REALbasic and is brought to you by REALbasic Developer, the magazine for REALbasic programmers.

Each week we answer select reader questions, and we're always open to ideas for future columns. Send your questions to . (Keep your questions simple and specific. General queries like "How do I write my own web browser?" will be neglected.) Your question won't be answered immediately, but will be answered in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise it's fair game.)

About the Author
is an author, philosopher, graphic designer, photographer, film director, soccer fanatic, and programmer (among other things). He writes for MacOpinion, runs his own software company, Stone Table Software, which sells the revolutionary Z-Write word processor, and is Publisher and Editor of REALbasic Developer. He lives in Northern California with his cats, Mischief and Mayhem, and is rapidly running out of free time.

See the REALbasic University Archives


REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.

.

.