Published: April 3, 2007
Last updated: June 21, 2007
By Richard G. Baldwin
Alice Programming Notes # 150
Part of a series
This tutorial lesson is part of a series designed to teach you how to program using the Alice programming environment under the assumption that you have no prior programming knowledge or experience.
Have some fun
Because Alice is an interactive graphic 3D programming environment, it is not only useful for learning how to program, Alice makes learning to program fun. Therefore, you should be sure to explore the many possibilities for being creative provided by Alice while you are learning to program using these tutorials. And above all, have fun in the process of learning.
In the previous lesson titled "World-Level Methods" I taught you how to write and use world-level methods that require parameters. I also taught you about some restrictions (relative to more conventional OOP programming environments) that exist in the Alice approach to passing and using parameters of type Object.
In this lesson, I will teach you how to:
I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.
Once you have mastered Alice, I recommend that you also study the other lessons in my extensive collection of online programming tutorials. You will find a consolidated index at www.DickBaldwin.com.
You can define new methods at either of two levels in Alice. Although the procedure for writing and using methods at those two levels are very similar, there are some differences that I will explain later in this lesson. In any event, the two levels are commonly referred to as follows:
You learned a lot about writing world-level methods with no parameters in the earlier lesson titled "Learn to Program using Alice, The Program Development Cycle." Later on you learned about writing world-level methods with parameters in the lesson titled "Learn to Program using Alice, World-Level Methods." (See Resources for links to both lessons.)
Once you know how to write world-level methods, you also know most of what you need to know to write class-level methods. As far as the method itself is concerned, there is very little difference between writing world-level methods and class-level methods. The main difference is the location of the button that you click to cause the skeleton for the method to appear as a new tab in the edit pane. Therefore, I won't go over that material again in this lesson. Rather, in this lesson, I will concentrate on the impact of class-level methods on the overall scheme of things. In particular, if you write new class-level methods, you can create new classes that include those methods for use in future programs. That brings us to the topic of inheritance.
The three pillars
Since 1997, I have taught several thousand students at the community college level how to do object-oriented programming (OOP) using Java. Early in every semester, I tell those students that every true OOP language must support the following three programming concepts:
In my opinion, if a programming language doesn't support all three, it really is not an OOP language.
I will provide a very brief treatment of these three topics in this lesson. If you would like to learn more about these topics, visit my website (see Resources) where you will find detailed coverage of these three topics for Java and C#, and some coverage for C++.
Alice is not an object-oriented programming language
Alice supports encapsulation fairly well. It makes a modest attempt to support inheritance. There is no semblance of support for polymorphism in Alice. Therefore, in my opinion, Alice is not an object-oriented programming language. Rather, it is an object-based language.
Despite that, I consider Alice to be an outstanding teaching and learning language for getting new programming students started down the right path towards OOP.
What is a class?
In OOP, a class is a blueprint from which objects can be created. (Later on, I will refer to a class as a recipe. Sometimes I refer to a class as a set of plans.) The Alice gallery contains several hundred classes from which you can create objects and add them to your worlds. For example, Figure 1 shows a screen shot of the thumbnail for the class named Hare in the gallery. Note the word Class that appears in the top of the image.
Figure 1. The thumbnail for the class named Hare in the gallery.
Creating your own classes
In more conventional OOP languages, you can start from scratch and create your own classes. However, that is not possible in Alice. (Actually, in Java and C#, all new classes are rooted in the class named Object, but that is not the case for C++.)
Also in more conventional OOP languages, you can start with an existing class and create a new class by extending the existing class.
When a new class extends an existing class, an object of the new class will contain all of the variables (properties in Alice) and all of the methods (class-level methods in Alice) that are defined in the existing class, plus all of the variables and all of the methods that are inherited into the existing class from all of its ancestors in the inheritance family tree. In other words, all of the variables and all of the methods are inherited into an object of the new class going all the way up the family tree to the topmost class in the inheritance hierarchy.
Typically, (but not necessarily) the new class will be a more specialized version of the existing class. For example, you might define a class named Animals. Then you might extend that class into two new classes named Carnivores and Herbivores to represent more specific types of animals. Then you might extend the Carnivores class into classes named Dog, Wolf, Lion, etc., to represent even more specialized types of animals. You might extend the Herbivores class into new classes with names like Cow, Sheep, Horse, etc. Typically, the new classes would add methods and variables that are more appropriate for an object of the more specialized class.
Does Alice support inheritance?
Alice supports inheritance in a very modest way, but typical Alice literature doesn't expose the fact that inheritance is in play. In the sample programs in this lesson, I will extend the Hare class into a new class named SpinningHare. An object of the SpinningHare class is a more specialized type of hare than the hares represented by the Hare class in the gallery. In particular, a SpinningHare object knows how to stand in one spot and spin around when requested to do so. Ordinary Hare objects don't have that capability.
Procedure for extending a class
To extend a class that is located in the gallery, do the following:
A new class
Although the nomenclature in the menu doesn't indicate such, when you complete that procedure, you will have defined a new class that extends the class from which your original object was created. Any object that you create from the new class will contain all of the variables and methods that belonged to the original class, plus all of the methods and variables that you defined before selecting save object...
You can now use this new class to create any number of new objects in the same program, or in future programs. This class supplements the classes in the gallery, but the (official) procedure for creating an object of the new class is different from the procedure for creating an object from a class in the gallery.
Which is right, save object... or save class...?
Consider the following scenario. Assume that you invite me for dinner and prepare an especially complex but tasty dish. During dinner, I compliment you on the dish and ask you to provide me with a small sample of the dish to take home with me so that I can prepare an identical dish next week.
What's wrong with this picture?
No doubt you will recognize the fallacy of my request. Having a sample of a complex dish containing many different ingredients would not be very helpful to me next week in preparing an identical dish. For starters, I would probably need to take my sample to an analytical chemistry lab and ask them to identify all of the different ingredients as well as the quantity of each ingredient.
What I really need is the recipe
However, it is likely that having that information would not be sufficient for me to prepare an identical dish. Although I know very little about cooking, I am led to believe that knowledge of various preparation and cooking techniques is necessary to prepare and cook complex dishes. What I should have asked for instead of a small sample was the recipe for the dish.
The Alice program was written in Java
I have read that the Alice program was written in Java. I suspect that when you click the save object... item as described above, you are not actually saving the object (a small sample of the dish). I suspect instead that what you are saving is the class (the recipe) from which additional objects can be created. I base this suspicion not only on many years of professional Java OOP experience, but also on the fact that the extension on the resulting file (a2c) is the same extension as most of the files in the directory named Alice\Required\gallery\Animals. For example, this directory contains a file named Hare.a2c, which represents the class named Hare in the gallery. As shown in Figure 1, the thumbnail image that represents that file identifies it as a Class.
Adding a new class to the gallery
I have also discovered experimentally, that you can add your new class to the gallery simply by copying it into one of the sub-directories of the directory named Alice\Required\gallery. If you do that, it will appear in the gallery with a thumbnail similar to that shown in Figure 2. (Compare this with Figure 1.)
Figure 2. The thumbnail for a new class added to the gallery.
To replace the image shown in Figure 2 with an image of your choice, do the following:
Creating objects from the new class
Once you place the file for your new class in the gallery, you can add it to new worlds in the same way that you normally add objects from the gallery without the requirement to use the Import... item on the File menu (to be discussed later). Just drag the thumbnail for the new class from the gallery into the picture of the world, or click on the thumbnail and then click the button labeled Add instance to the world.
Creating a new folder for classes in the gallery
Taking this concept even further, you can create a new folder to be used as the repository for classes in the gallery by creating a new directory as a child of the directory named Alice\Required\gallery. Then you can store your new custom classes in that folder. For example, the leftmost thumbnail in Figure 3 shows the thumbnail for a new folder in the gallery named A-Custom.
Figure 3. Thumbnail for a new folder in the gallery.
To replace the image shown in Figure 3 with an image of your choice, do the following:
Making life easier
This makes it easy for you to create a library of new classes and easily add objects of those new classes to your worlds simply by following the normal procedures for adding objects from the gallery. Be aware, however, that if you later find it necessary to re-install Alice 2.0, your new folder may not be there following the installation. Therefore, you should include that folder in your daily backup routine so you will have it available to be copied back into the gallery. (You do have a daily backup routine, don't you?)
An editorial opinion of the save object... item on the popup menu
Therefore, in my opinion, the use of the term save object... on the popup menu is not only confusing to students, it is probably technically incorrect. Also in my opinion, it would have been better if the Alice developers at Carnegie had used the term save class... instead. Why does it matter? It matters because learning object-based programming is confusing enough for students when the terminology is correct. The use of incorrect and confusing terminology just makes matters worse.
Procedure for creating objects from your new class
Perform the following steps to create an object from the new class and add it to your world.
Not required to be in scene edit mode
Note that unlike adding objects from the gallery, you are not required to be in scene edit mode when you use this procedure for creating new objects and adding them to your world.
New object should appear
When you complete the procedure described above, the new object should appear in the object tree, and should also appear in the picture of your world.
My experience is that if you create two or more such objects from the same new class, they will overlay one another in the picture. You may need to separate them visually using the mouse if you want to manipulate them visually using the mouse.
What is the default name of the new object?
Also be aware that unlike creating objects from the gallery, the name that is given to the new object may have no apparent relationship to the name of the class. It appears experimentally to be based on the name of the class from which your original object was created instead.
Examine the methods belonging to the object
Once you have created an object of your new class, select it in the object tree and then select the methods tab below the object tree. All new methods that you added to the original class should now show up as tiles in the methods tab, ready to be dragged into the edit pane for inclusion in your code. Similarly, if you select the properties tab, all new variables (properties) that you added should show up as tiles in the properties tab ready for use in writing your program.
Writing class-level methods
To write a class-level method, do the following:
From this point forward, the procedure is no different from the procedure for writing world-level methods. You learned how to write world-level methods in the lesson titled "World-Level Methods" (see Resources).
Declaring class-level variables (properties)
To declare and initialize class-level variables, do the following:
From this point forward, the procedure is no different from the procedure for declaring and initializing local variables. You learned how to declare and initialize local variables in the lesson titled "Data Types and Variables" (see Resources).
A word about polymorphism
In more conventional OOP languages, you can define two or more methods having the same name either in a given class or up and down the class hierarchy.
If the method names are the same but the argument lists are different this is commonly referred to as method overloading. If the methods names and the argument lists are the same, this is referred to as method overriding.
Each of these procedures represents a form of polymorphism, which is not allowed in Alice. In Alice, if you try to define a new method with the same name as an existing method in the same class hierarchy, the name that you type in turns red and the OK button becomes disabled. This prevents you from defining two methods in the same class hierarchy having the same name.
Changing the behavior of existing methods
Although you can modify existing methods (including primitive methods) to change their behavior, that is probably not a good idea. If you need behavior that is similar to but different from the behavior of an existing method, you should write a new method with a different name, copy the code from the existing method into the new method, and then edit the new method to modify the behavior of the new method relative to the old method.
In this lesson, I will present and explain two programs that illustrate the process of extending a class into a new class, and later using that new class to add objects to a world.
Won't provide downloadable version
The two programs in this lesson are extremely simple, and I will provide the source code for both of them in Listing 1 and Listing 2. However, most of the effort required to develop these two programs takes place manually before you ever start writing code. Therefore, I won't provide downloadable executable versions of the programs.
Description of the two programs
The purpose of the program named Alice0150a is to define and save a new class named SpinningHare.a2c. This class adds a method named spin to the standard Hare class. Objects of this class can be created and added to a world by importing the class using the Import... item on the File menu.
The purpose of the program named Alice0150b is to illustrate how to use the new class named SpinningHare.a2c. During the manual setup phase, you must use the Import... item on the File menu to add two objects created from this class to your world. To be consistent with the code in Listing 2, you will need to rename the two objects spinningHare1 and spinningHare2.
The source code for this program is shown in Listing 1.
Define your new class
To define your new class, you need to:
Test your method
To test your method, you need to write and run the main method shown in Listing 1. Note that I included the primitive method named move in addition to the new method named spin in the main method to demonstrate that the new method is available for execution in addition to the primitive methods.
Save your new class
To save your new class, you need to:
The source code for this program is shown in Listing 2. The purpose of this program is to illustrate the use of the new class named SpinningHare to add new objects to your world. To run this program, do the following:
Once again, I included calls to the move method in addition to calls to the spin method in Listing 1 to demonstrate that the object created from the new class contains the new method named spin in addition to the primitive methods.
I encourage you to follow the procedures described in this lesson to write the programs illustrated in Listing 1 and Listing 2. Experiment with the programs, making changes, and observing the results of your changes.
In this lesson, I taught you how to:
The next lesson will teach you about the different kinds of errors (syntax errors, runtime errors, and logic errors).
There is no formal lab project for this lesson, simply because the logistics of developing, saving, and submitting a program that requires a new class in a college environment where many students use the same computer, and each student uses many different computers are somewhat impractical.
However, for your own educational benefit, I recommend that you create and then use a new class named BetterHare where the more specialized version of the Hare class not only knows how to spin, but also knows how to jump.
Resources from earlier lessons in the series titled "Learn to Program using Alice"
Listing 1. Source code for the program named Alice0150a.
Created by: Dick Baldwin
Listing 2. Source code for the program named Alice0150b.
Created by: Dick Baldwin
Copyright 2007, Richard G. Baldwin. Faculty and staff of public and private non-profit educational institutions are granted a license to reproduce and to use this material for purposes consistent with the teaching process. This license does not extend to commercial ventures. Otherwise, reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.
Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.
In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP). His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments. (TI is still a world leader in DSP.) In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.
Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.