Unit 5: Writing Classes

This unit covers the fundamentals of object-oriented programming, including class design, constructors, methods, and encapsulation.

Key Concepts

  • Class Structure: Components of a class
  • Instance Variables: Object attributes
  • Constructors: Object initialization
  • Methods: Object behaviors
  • Access Modifiers: public, private, protected
  • Encapsulation: Data hiding and accessors
  • Method Overloading: Multiple method signatures
  • this Keyword: Referring to current object

Example Code


// Example: Writing Classes in Java
public class Student {
  // Instance variables (private for encapsulation)
  private String name;
  private int age;
  private double gpa;
  
  // Constructor
  public Student(String name, int age) {
    this.name = name;
    this.age = age;
    this.gpa = 0.0;
  }
  
  // Overloaded constructor
  public Student(String name, int age, double gpa) {
    this.name = name;
    this.age = age;
    this.gpa = gpa;
  }
  
  // Accessor methods (getters)
  public String getName() {
    return name;
  }
  
  public int getAge() {
    return age;
  }
  
  public double getGpa() {
    return gpa;
  }
  
  // Mutator methods (setters)
  public void setName(String name) {
    this.name = name;
  }
  
  public void setAge(int age) {
    if (age >= 0) {
      this.age = age;
    }
  }
  
  public void setGpa(double gpa) {
    if (gpa >= 0.0 && gpa <= 4.0) {
      this.gpa = gpa;
    }
  }
  
  // Other methods
  public void study() {
    gpa += 0.1;
    if (gpa > 4.0) gpa = 4.0;
  }
  
  @Override
  public String toString() {
    return "Student[name=" + name + ", age=" + age + ", gpa=" + gpa + "]";
  }
}

// Main class to test Student
public class StudentTest {
  public static void main(String[] args) {
    Student student1 = new Student("John", 18);
    Student student2 = new Student("Jane", 19, 3.8);
    
    System.out.println(student1);
    System.out.println(student2);
    
    student1.study();
    System.out.println("After studying: " + student1);
  }
}
              

Writing Classes

Class Components:

Component Description Example
Instance Variables Data fields of a class private String name;
Constructor Initializes objects public Student(String n) { name = n; }
Methods Behaviors of a class public String getName() { return name; }
Access Modifiers Control visibility public, private, protected

Class Example:


public class Student {
    // Instance variables
    private String name;
    private int grade;
    private double gpa;

    // Constructor
    public Student(String n, int g, double gpa) {
        name = n;
        grade = g;
        this.gpa = gpa;
    }

    // Methods
    public String getName() {
        return name;
    }

    public void setName(String n) {
        name = n;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int g) {
        grade = g;
    }

    public double getGPA() {
        return gpa;
    }

    public void setGPA(double gpa) {
        this.gpa = gpa;
    }

    public String toString() {
        return name + " (Grade " + grade + "): " + gpa;
    }
}
              

Class Design Tips:

  • Use meaningful names for classes and methods
  • Keep instance variables private
  • Provide appropriate accessor and mutator methods
  • Include a toString() method
  • Consider implementing equals() and hashCode()

Common Pitfalls and Debugging Tips

Common Mistakes:

  • Shadowing Variables: Parameter names matching instance variables
    
    public void setGPA(double gpa) {  // Wrong! Parameter shadows instance variable
        gpa = gpa;  // Does nothing
    }
    public void setGPA(double gpa) {  // Correct! Use this keyword
        this.gpa = gpa;
    }
                      
  • Missing Constructor: Forgetting to initialize instance variables
    
    public class Student {
        private String name;  // Wrong! Not initialized
        public Student() { }  // Empty constructor
    }
    public class Student {
        private String name = "";  // Correct! Initialize
        public Student() { }
    }
                      
  • Incorrect Access: Using wrong access modifiers
    
    public String name;  // Wrong! Should be private
    private String name;  // Correct! Encapsulation
                      

Debugging Tips:

  • Use toString() for object inspection
  • Check constructor initialization
  • Verify method parameter types
  • Test edge cases in methods
  • Use IDE debugger for object state

AP Exam Tips:

  • Know how to write class definitions
  • Understand encapsulation principles
  • Be able to write constructors
  • Know how to implement methods
  • Understand access modifiers

AP Exam-Style Practice Problems

Problem 1: Class Definition

Consider the following class definition:


public class Book {
    private String title;
    private String author;
    private int pages;

    public Book(String t, String a, int p) {
        title = t;
        author = a;
        pages = p;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public int getPages() {
        return pages;
    }
}
                

Which of the following is NOT a valid method to add to the Book class?

public void setTitle(String t) { title = t; }
public String toString() { return title + " by " + author; }
public void setPages(int p) { pages = p; }
public void getTitle(String t) { title = t; }
The correct answer is D. A getter method should not modify the instance variable and should not take parameters.
Problem 2: Constructor

Consider the following class definition:


public class Circle {
    private double radius;
    private double area;

    public Circle(double r) {
        radius = r;
        area = Math.PI * radius * radius;
    }

    public double getRadius() {
        return radius;
    }

    public double getArea() {
        return area;
    }
}
                

What is the output of the following code?


Circle c = new Circle(2.0);
System.out.println(c.getArea());
                
12.566370614359172
4.0
6.283185307179586
3.141592653589793
The correct answer is A. The area is calculated as πr², where r = 2.0, resulting in approximately 12.57.
Problem 3: Method Implementation

Consider the following class definition:


public class Rectangle {
    private int width;
    private int height;

    public Rectangle(int w, int h) {
        width = w;
        height = h;
    }

    public int getArea() {
        return width * height;
    }

    public int getPerimeter() {
        return 2 * (width + height);
    }
}
                

Which of the following methods would correctly determine if a rectangle is a square?

public boolean isSquare() { return width == height; }
public boolean isSquare() { return width = height; }
public boolean isSquare() { return getArea() == getPerimeter(); }
public boolean isSquare() { return width * height == width + height; }
The correct answer is A. A square has equal width and height, so we compare them using the equality operator.

Practice Problems

  1. Create a BankAccount class with methods for deposits, withdrawals, and balance checking.
  2. Design a Rectangle class with methods to calculate area, perimeter, and check if it's a square.
  3. Implement a Time class that handles hours, minutes, and seconds with appropriate validation.

Tips for Success

  • Always use proper encapsulation with private instance variables.
  • Include appropriate constructors for object initialization.
  • Validate data in mutator methods.
  • Use meaningful method and variable names.
  • Include toString() method for debugging.

Interactive Code Playground

Try out your own class writing code here!

Output:
Note: This is a simulated environment. For actual Java code execution, please use an IDE or online Java compiler.

For actual code execution, we recommend using: