Class Interfaces
From Real Software Documentation
Aim In this lesson, we will examine our last major OOP feature in Real Studio: the Class Interface.
Contents |
The Essence of Type
The notion of type that we have been working with amounts to this: a type is a name and a set of operations (properties and methods).
Since we can always create getter and setter methods for any properties a type might require, the simplest possible notion we can arrive at for a type is a name and a set of method definitions. (Notice that by method definitions, we don’t mean the actual code of the methods, but just their names and arguments[note 1]).
This is precisely what an interface is: a name and a set of method definitions. We can create a new type by creating an interface and assigning it method definitions. We can make a class have that type by adding the name of the type to its Interfaces property, and by making sure it supports all of the methods defined by the interface.
Notice that this idea is quite separate from inheritance. Inheritance from a common superclass guarantees that two classes will have the same methods, and thus that they can be treated as the same type. But inheritance goes beyond the minimum required, by providing implementations of methods, along with properties.
Another way of describing the difference between an interface and class inheritance is this: an interface defines a type, but inheritance also provides at least part of the implementation.
The obvious question now is: Why would we not want a class to get at least part of the implementation when we assign it a type? (Why even have this “lite” way of defining a type at all?) The answer is: It avoids many complications when we want our programming language to let our classes have more than one type.
Multiple Types
As you start developing more complex programs, it quickly becomes natural to want to give a single class more than one type.
The most obvious example is the built-in classes: we might want these to take on extra roles, and the natural way to do this is to provide them with extra polymorphic types. In the program we will construct in this lesson, we will extend the word counter project so it can display its result in either a ListBox or in a TextField.
The correct way to do this in an object-oriented programming language like Real Studio is to give these two classes the same type, thereby assigning them suitable operations for displaying the word count.
But Real Studio only allows us to assign one superclass to a class. The obvious question now is: why can’t a class have multiple superclasses?
Only One Superclass
There are good reasons for only allowing one superclass for a given class. Programming languages that allow you to have more than one superclass run into a variety of complications. For instance, what if the two superclasses both have a method or a property with the same name? What about when the two superclasses themselves have a common superclass?
In a programming language that supports multiple inheritance like this, assume Class1 has a property Size. This means that both Class2 and Class3 have a Size property. Should Class4 have one Size property, or two (presumably, we’d have some way of renaming one of them)? The answer is that it depends: you might want just one property, but you might want two. There are other complications, such as what happens to a method from Class1 that is modified in Class2, but not in Class3.
Considerations like this mean that programming languages supporting multiple inheritance have convoluted and often difficult to maintain mechanisms for controlling how the inheritance is to be carried out.
Interfaces, since they carry no implementation, avoid this problem.
An Even Better Word Counter
- Open the project from Lesson 9 (the word counter that can count both files and the clipboard).
- Add a TabPanel to Window1 (read about how to use TabPanels in the User’s Guide).
- Give it two panels called “List” and “Text”.
- Position the ListBox on the first panel of the TabPanel and place the PushButtons under the TabPanel.
- Click on the second tab and add a TextArea called “WordLister” to it.
- If they are not already on, turn on the TextArea’s MultiLine and ScrollBarVertical properties.
This is what you see when you switch to page 2 of the TabPanel.
Examine the methods and properties defined in Window1 and consider why, in the light of what we’ve learned in recent lessons, these more appropriately belong in a separate class; Think about what form that class might take (it will need all the methods and properties defined in Window1, for a start…).
- Create a WordCountList class, and move the methods and properties from Window1 to the new class.
- Add a WordCounter As WordCountList property to Window1.
- Add an Open event handler to the Window, with code to initialize WordCounter: WordCounter = New WordCountList
- Open the code in either of the buttons, and think about how it needs to be modified to accommodate the new object.
The top parts of the code will be easy to change, but an interesting issue will arise when you consider how to display the results. You might be tempted to add Get methods to the WordCountList class, so you can loop over the list of words and display their contents, just as we have been doing.
Doing that would be poor design.
Give Objects High-Level Behavior (or “Think Twice About Accessor Methods”)
This part is very important. It is an example of the kinds of things you need to learn to be a good object-oriented programmer.
You should think twice about any design involving Get and Set methods (also known as Accessor Methods). While they are often appropriate, you should see if there is a better design solution. Any such solution will usually involve giving higher-level methods to the object you were tempted to add accessor methods to. By “higher-level”, we mean something like “more sophisticated” or “performing a larger task.”
The current design we are putting together is an excellent example of this: the job of displaying the word count should be managed between the WordCountList class that will have the list of words, and the class that will be displaying that list.
A slightly different version of this design heuristic (meaning “rule of thumb”) is to say that the code to carry out a task should be distributed between just the objects that must be involved. This heuristic tells us that the button in the window should not contain any of the logic involved in displaying the count. This rule keeps our code simpler, gives us less places to look for problems, and makes the objects more portable between projects (or between different parts of the same project).
- Now that we have made our broad design decision, here is the code for the Clipboard button’s Action handler:Another good design would be to have the Display method execute the clear method itself; however, by separating that call, we keep a little extra flexibility to, say, display the word count in several stages, or from several sources.
- Choose Project ↠ Add ↠ Class Interface. Name it “WordCountDisplayer” in the Properties pane.
- Double-click the new class interface in the Project Editor and add two method definitions.
- Create a method named “Display” in the WordCountList class.
- Create a class “WordCountListBox”, with ListBox as its super.
- Click on its Interfaces property and enter “WordCountDisplayer”.
REAL Studio offers to add the interface methods to the new class. - Click Yes to add the specs for the Add and Clear methods to the new class.
- Implement suitable Add and Clear methods.Sub Clear()
DeleteAllRows - Change the code in the Action handler of the CountFile button to this. //Ask user for a file, then execute CountWords on thatfile,
//and copy the results into WordList
Dim counter As integer
Dim Source As FileSource
Dim f As FolderItem
Dim s As BinaryStream
Source = new FileSource
//Request file
f=GetOpenFolderItem("text/plain")
If f<>Nil then
s = BinaryStream.Open(f)
Source.SetFile s
WordCounter.CountWords(Source)
WordList.clear
WordCounter.Display WordList
End if - Use the Properties pane to change the ListBox to a WordCountListBox.
Before you proceed with following instructions, see if you can create the WordCountTextArea class yourself. You’ll have to decide how to display the results (perhaps one word to a line, and each line will look something like ‘apples: 3’).
If you need help, here is one way of doing the methods in the WordCountTextArea.Sub Add (w As String, c As Integer)
If Text = "" then
Text = Text + w + ": " + Str(c)
Else
Text =Text + Chr(13) + w + ": " + Str(c)
End ifSub Clear()Your code might look a little different to this, and it might display the results a little differently. That’s fine, as long as it works.
Text = ""
Don’t forget to add WordCountDisplayer to this class’s Interfaces property, and to change the TextArea on the second page of the TabPanel in Window1 to a WordCountTextArea
- Run the program, stepping through the important parts if it’s not clear how it works.
Questions and Conclusions
Class Interfaces are an important tool for producing the best REAL Studio program designs. You now have all the tools you need to simplify and structure your code effectively using Polymorphism, wherever that is appropriate.
Further Exercises
Try some of the following exercises:
- Add a new WordCountDisplayerGroup class to the project. Its task is to store references to multiple WordCountDisplayers, and to ‘broadcast’ calls to each of the objects it refers to. So it is a WordCountDisplayer itself, but it also has an Add method, with a
WordCountDisplayer argument. The buttons need only then ask the Word counter to display itself in the WordCountDisplayerGroup, and that object will in turn ask each of the displayers to display the contents.
- Add the ability to “display” to a tab-delimited file. This would work nicely as a third “tab” that lets you choose the target file. To write this, you will need to research how to write to a file.
A Final Comment
Note that User’s Guide implies that interfaces are only to be used with controls, but this is not so: they are suitable for many situations with any type of object.
Take-home assignment: Writing to a File
Your task is to add a new WordCountDisplayer to the word counting project we’ve been working on. This new class will write the word count to a file. At a minimum, you’ll need to read the section Getting a File at a Specific Location in the REAL Studio User’s Guide. You should also read Understanding FolderItems, and Working with Text Files. The text file should be tab-delimited, meaning that each word and its count is written to the file as its word, followed by a tab, followed by the count (as a string), and then followed by a return character (ASCII 13). You should first write a class that just sends the information to a file with a fixed name on the desktop. Look up the DesktopFolder function in the built-in reference for information and examples on using this function. After you get that working, you should modify it so that it can be given a path or a folderitem (your choice) to save the information to. You should add panel to the Tabpanel with a button that lets the user create the file to contain the information. You should display the chosen path in an EditField on the tab control. You might like to add a checkbox to turn this export on or off, as well. Look up GetSaveFolderItem to find out how to display a standard file save dialog. You should also look up the FolderItem class to find out how to get information such as the path out of the FolderItem after the user has created the file.
References
- Notes

