Goals

The goals of this lab are to learn the following:

Computer Science Principles Curriculum

Common Core Standards

Overview

In this lab, you will learn how to use class variables, accessor actions, access modifiers, and a constructor. You will create a basic Car class to learn and observe how they work with a Main class. You will start with defining and experimenting with class variables, then you will work your way up to using class variables with accessor actions and access modifiers. Next, you will make action calls to a Car object in the Main class and understand how a constructor works. At the end of the lab, you will fine-tune your program by organizing the code and practice more with actions. The goal of this lab is to help you learn and master object-oriented programming, as this is a very important part of programming!

Activity:

You can use this IDE (Integrated Development Environment) for all your coding in this lesson instead of using Sodbeans:

Task 1: Getting Started

Start Sodbeans. Create a new “Quorum Application” project, and name it Lab5_2. In the Main.quorum file, it should contain a Main class and Main action as shown below:

class Main
    action Main
    end
end

You will create an additional class in the project. In the New File dialog, create a new file by selecting “Quorum” and “Quorum Class” in the Categories and File Types windows, respectively. Then, name the new file Car in the New Quorum Class dialog. The Car class will appear with the following code:

class Car
end

You will fill Car and Main classes with the code in the next four tasks.

Task 2: Creating Class Variables

You are going to create class variables and experiment with how they work between two classes. There are two ways to control access to class variables: you can use access modifiers and accessor actions (getters and setters) or by making the class variables public. In programming, you typically want to write code that is secure and encapsulated. Encapsulation is one of the four fundamental object oriented programming concepts. It is the technique of making class variables private and providing access to them with public actions. If a variable is private, then it can't be accessed by anything outside of the class is was created in, except through the use of getters and setters. This is also known as data hiding. Encapsualtion gives maintainability, flexibility, and extensibility to your code.

In the Car class, add two class variables:

The code should look similar to the following:

class Car
    public integer numberOfDoors = 4
    private text color = "Blue"
end

Then, in the Main class, you will add the code that will access class variables from the Car class. You will need to create a Car object in order to use its variables and actions. You only have two variables for now, so do the following to access them:

It should look like the sample code shown below:

class Main
    action Main
        Car car
        car:numberOfDoors = 4
        car:color = "Blue"
    end
end

Run the program and observe what happens. Answer the following questions:

Task 3: Creating and Using Access Modifiers and Accessor Actions

Now that you know how to use class variables and control access to them, you are going to apply the class scoping concept to class variables. Class scoping allows you to use class variables anywhere in a class to pass values around and make any changes to the stored values in the variables. You are going to learn how to take advantage of class scoping by creating and calling accesor actions and access modifiers (getters and setters).

Before you get started with accessor actions and access modifiers, you will need to make changes to class variables in the Car class. Since you are going to use getters and setters, you don’t want variables to be defined public, so you will make them private. The private keyword is optional in Quorum, because Quorum automatically defines class variables as private variables. You will let Quorum do the work for you. Make changes to a Car class to match the following code sample:

class Car
    integer numberOfDoors = 4
    text color = “Blue”
end

Let’s use private class variables to set up accessor actions and access modifiers to allow a Main class to access them. You will start with the numberOfDoors variable. First, create an accessor action and name it GetNumberOfDoors. It has no parameter and returns an integer value for a number of doors on a car. Next, create an access modifier to modify a number of doors on a car. Name it SetNumberOfDoors. It has a parameter and no return value. The parameter is an integer value used for setting a new value for a number of doors. The code should look like the following:

class Car
    integer numberOfDoors = 4
    text color = "Blue"
    action GetNumberOfDoors returns integer
        return numberOfDoors
    end
    action SetNumberOfDoors(integer value)
        numberOfDoors = value
    end
end

The accessor actions and access modifiers always start with “Get” and “Set” in their names, respectively. This helps you recognize a type of an action and the purpose of its name.

It’s time to make calls to a Car object! Switch to the Main class. Use a Car object to call both GetNumberOfDoors and SetNumberOfDoors actions. The Main class should look similar to the following:

class Main
    action Main
        Car car
        car:GetNumberOfDoors()
        car:SetNumberOfDoors(2)
    end
end

This basically gives you an idea of how to make action calls to the getters and setters. Modify the code so that it matches the output shown below:

The car has 4 doors.
The car has 2 doors.

The first call should get the current value of a number of doors. The second call should change a number of doors from four to two. The final call displays a new change that has been made to the numberOfDoors variable.

Add a getter and setter for the color variable in the Car class. Do the same that you did for the numberOfDoors variable in the Main class. The color of a car should be set to “Black.” The output should match the following:

The car has 4 doors.
The color of a car is Blue.
The car has 2 doors.
The color of a car is Black.

Task 4: Defining a Constructor

In this task you are going to define a constructor to initialize class variables. When an object is instantiated, a constructor is immediately called to execute the code within a constructor. The constructor can do a variety of things, but you will focus on initializing class variables for this lab. It is always a good practice to initialize variables to the default values in a constructor. For example, if a user does not choose a number of doors and the color of a car, the default values will be used.

In a Car class, create a constructor between class variables and the first accessor action. In a constructor, initialize numberOfDoors to four and color to Silver. Since you are initializing variables in a constructor, you no longer need to initialize class variables outside the constructor and actions. The code should match the following part of a Car class:

class Car
    integer numberOfDoors = 0
    text color = ""
    on create
        numberOfDoors = 4
        color = "Silver"
    end
    action GetNumberOfDoors returns integer
        return numberOfDoors
    end
    …
end

You don’t have to make any changes to the Main class. Run the program and it should still function as before.

Task 5: Fine-tuning Car and Main Classes

In this final task, you are going to fine-tune a program to add user input checking to the access modifiers in the Car class and enhance the code in the Main class.

In the Car class, add the user input checking code to two setters based on the following descriptions:

In the Main class, make action calls to set a number of doors to three and the color of a car to Purple. Output or speak the output to see what happens to the invalid values. The output should look like the following:

The car has 4 doors.
The color of a car is Silver.
The car has 2 doors.
The color of a car is Black.
The car has 2 doors.
The color of a car is Red.

You are going to make one more change to a Main class. You are making a series of action calls with the same code, so you are going to convert them into two separate actions for a better reusability.

Use the code snippet below to add new actions in a Main class:

/* Action Change has three parameters and no return value. The first
* parameter is a Car object, the second parameter is a number of doors,
* and the third parameter is the color of a car.
* This action modifies the existing values of a number of doors and the
* color of a car.
*/
action Change(Car vehicle, integer numDoors, text color)
   // Insert the code here
end

/* Action Display has one parameter and no return value. The first parameter
* is a Car object.
* This action outputs a number of doors and the color of a car to the user.
*/
action Display(Car vehicle)
   // Insert the code here
end

Notice that you are passing a Car object into actions. This is one of ways to pass an object around in the class. You will learn how to apply the class scoping concept to an object in the next lab.

Fill these actions with the appropriate code. Call both Change and Display actions with the same values. The program should still function the same with same results in the output as before. Show the work to the instructor.

Next Tutorial

In the next tutorial, we will discuss Lab 5.3, which describes an introduction to arrays..