Introduction

A class serves as a blueprint for creating objects in programming. It encapsulates data and methods that operate on that data. To define a class, specify its access level (public or private), use the class keyword, and provide a name. Inside the class, you define variables to hold data and methods to perform operations. For instance, in the AreaCalculator class, you can define instance variables and methods to calculate areas of various shapes, illustrating how classes structure and manage data and functionality.

Anatomy of a Class

A class is a blueprint for creating objects, containing variables and methods to manage data and perform actions. To define a class, specify its access level (public or private), use the class keyword, and provide a name. Enclose the class contents within curly braces {}. For example, the AreaCalculator class can be defined as follows:

public class AreaCalculator {}

Inside the curly braces, you can declare instance variables to store data and methods to perform operations. For instance, an AreaCalculator class might include an instance variable to track the number of shapes processed:

public class AreaCalculator {
    private int numShapes;
}

The numShapes variable is private to restrict access from other classes, ensuring it is only accessible within the AreaCalculator class.

Constructors

Constructors are special methods used to initialize objects of a class. They have the same name as the class and no return type. Every class must have at least one constructor, and if none is provided, a default constructor is created. Constructors should be public so that objects can be instantiated from other classes.

For example, the AreaCalculator class includes a constructor to initialize the numShapes variable:

public class AreaCalculator {
    private int numShapes;

    public AreaCalculator() {
        numShapes = 0;
    }
}

Constructors can also take parameters to initialize instance variables with specific values. For example, the Car class has a parameterized constructor:

public class Car {
    private String brand;
    private String model;
    private int year;

    public Car(String make, String carModel, int yearMade) {
        brand = make;
        model = carModel;
        year = yearMade;
    }
}

In this case, constructor parameters are used to set the initial values of brand, model, and year.

Accessor Methods

Accessor methods, also known as getters, are used to retrieve the value of private instance variables from outside the class. They are public methods that return the value of a variable without modifying it.

For example, to access the numShapes variable in the AreaCalculator class, you can create an accessor method like this:

public class AreaCalculator {
    private int numShapes;

    // Accessor method for numShapes
    public int getNumShapes() {
        return numShapes;
    }
}

Accessor methods typically have a return type matching the variable’s type and usually consist of a single line that returns the value of the variable.

Mutator Methods

Mutator methods, also known as setters, are used to modify the value of private instance variables. They are public methods that typically have a void return type and accept parameters to update the variable.

For example, in the Car class, a mutator method for the year variable might look like this:

public class Car {
    private int year;

    // Mutator method for year
    public void setYear(int newYear) {
        year = newYear;
    }
}

Mutator methods allow you to change the value of instance variables after an object has been created, providing a controlled way to modify data.

Writing Methods

Methods are used to perform actions and compute values within a class. They can take parameters and return values. For instance, in the AreaCalculator class, you might write methods to calculate the area of different shapes. When writing methods, remember that primitive types are passed by value, meaning changes to parameters do not affect the original variables. Objects are passed by reference, so changes to an object’s attributes inside a method will affect the original object.

Here are examples of methods for calculating areas in the AreaCalculator class:

public class AreaCalculator {
    private int numShapes;

    // Method to calculate the area of a triangle
    public double triangleArea(double base, double height) {
        double area = (base * height) / 2;
        numShapes++;
        return area;
    }

    // Method to calculate the area of a rectangle
    public double rectangleArea(double length, double width) {
        double area = length * width;
        numShapes++;
        return area;
    }

    // Method to calculate the area of a trapezoid
    public double trapezoidArea(double base1, double base2, double height) {
        double area = (base1 + base2) * height / 2;
        numShapes++;
        return area;
    }
}

Each method performs a calculation and updates the numShapes variable to reflect that a shape’s area has been calculated.

Static Variables and Methods

Static variables and methods belong to the class rather than to any specific object. They are shared across all instances of the class and can be accessed without creating an object. To define a static variable or method, use the static keyword.

For example, in the AreaCalculator class, you can make numShapes and the area calculation methods static:

public class AreaCalculator {
    private static int numShapes;

    // Static method to calculate the area of a rectangle
    public static double rectangleArea(double length, double width) {
        double area = length * width;
        numShapes++;
        return area;
    }

    // Static method to calculate the area of a triangle
    public static double triangleArea(double base, double height) {
        double area = (base * height) / 2;
        numShapes++;
        return area;
    }

    // Static method to calculate the area of a trapezoid
    public static double trapezoidArea(double base1, double base2, double height) {
        double area = (base1 + base2) * height / 2;
        numShapes++;
        return area;
    }

    // Static method to get the number of shapes calculated
    public static int getNumShapes() {
        return numShapes;
    }
}

Static methods and variables are accessed using the class name, like AreaCalculator.rectangleArea(5.0, 3.0), without needing to instantiate an AreaCalculator object.

Scope and Access

Scope refers to the visibility and accessibility of variables, methods, and other elements within a program. In Java, there are two main types of scope:

  1. Global Scope: Variables and methods with global scope are accessible from anywhere within the class. For example, instance variables defined outside of methods but inside the class have global scope within that class.

  2. Local Scope: Variables with local scope are accessible only within the block of code in which they are defined, such as within a method. For example, variables declared inside a method exist only during the execution of that method and are not accessible outside of it.

In the AreaCalculator class, the numShapes variable has global scope within the class, while the area variable used in methods like triangleArea has local scope:

public class AreaCalculator {
    private int numShapes; // Global scope within the class

    public double triangleArea(double base, double height) {
        double area = (base * height) / 2; // Local scope within this method
        numShapes++;
        return area;
    }
}

Understanding scope helps in managing variable visibility and avoiding conflicts, leading to more organized and efficient code.

This Keyword

In Java, the this keyword refers to the current instance of a class. It is used within an object’s methods to access its fields and methods. It helps to distinguish between instance variables and parameters or local variables with the same name and can also be used to pass the current object as a parameter to another method.

Here’s how you can use the this keyword:

  1. Accessing Instance Variables: To refer to the current object’s instance variables.
public class MyClass {
    int x;

    public void setX(int x) {
        this.x = x; // Refers to the instance variable
    }
}
  1. Passing the Current Object: To pass the current instance to another method or constructor.
public class MyClass {
    int x;

    public void setX(int x) {
        this.x = x;
    }

    public void updateX(MyClass obj) {
        obj.setX(this.x); // Passing the current object as an argument
    }
}

Using this helps to clarify which variables or methods are being accessed and ensures the correct context for operations on object data.

Additional Resources:

Quizlet
Runestone Academy

Hacks

Part 1

public class Rectangle {
    private double length;
    private double width;

    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    public double getLength() {
        return length;
    }

    public double getWidth() {
        return width;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double calculateArea() {
        return length * width;
    }
}

public class Main {
    public static void main(String[] args) {
        Rectangle rect1 = new Rectangle(5.0, 3.0);
        Rectangle rect2 = rect1;
        rect2.setWidth(4.0);
        System.out.println("Area of rect1: " + rect1.calculateArea());
    }
}

Answer the following questions based on the code above:

  • a) What is the output of the System.out.println("Area of rect1: " + rect1.calculateArea()) statement? Explain why.
  • Answer:
  • b) Do rect1 and rect2 refer to the same memory location? Explain your answer.
  • Answer:

Part 2

Situation: You are designing a system to manage employee records in a company. You need to create a class Employee and another class Company to manage multiple employees.

(a) Write a class Employee with private instance variables for name, id, and salary. Include a constructor to initialize these variables, accessor methods to retrieve their values, and mutator methods to update them.

(b) Explain how encapsulation is achieved in the Employee class. What is the role of accessor and mutator methods in achieving encapsulation?

(c) Code:

Create a class Company that contains an array of Employee objects. Include a method addEmployee(Employee newEmployee) to add a new employee to the array. Write the method signature and implementation, including comments to explain your code.