AP Computer Science A Writing Classes — Worked Answer Explanations

Unit 5 · 12 questions explained

Below is a complete answer key for our AP Computer Science A Writing Classes practice questions. For each question you'll find the correct choice, a full written explanation of how to get there, and — for every wrong answer — a short note on exactly why it's tempting and where it goes wrong. Reading these straight through is one of the fastest ways to find the gaps in a unit before exam day.

Prefer to test yourself first? Take the timed Writing Classes practice test and come back here to review, or head back to the Writing Classes unit overview.

In-content ad
  1. Question 1 · Easy

    Which of the following correctly defines a constructor for a Dog class?

    public class Dog {
        private String name;
        // Which option is a valid constructor?
    }
    
    • A
      public void Dog(String n) { name = n; }
      Why not A: Constructors have no return type — not even void. The presence of void makes this a regular method, not a constructor.
    • B
      public Dog(String n) { name = n; }Correct
    • C
      private Dog(String n) { name = n; }
      Why not C: A private constructor is syntactically valid but rarely used (prevents outside instantiation). The standard AP CSA convention uses public. However, this IS a valid constructor — Option B is more clearly correct for the AP context.
    • D
      public dog(String n) { name = n; }
      Why not D: The constructor name must exactly match the class name. The class is Dog (capital D); dog (lowercase) does not match and would be treated as a regular method missing a return type.
    Explanation

    A constructor has the same name as the class (exact match, including case) and has NO return type (not even void). Option B correctly defines a public Dog constructor that assigns the parameter to the instance variable.

    Key takeaway

    A constructor has the same name as the class and no return type — not even void.

  2. Question 2 · Easy

    What is the output of the following code?

    public class Counter {
        private int count = 0;
        
        public void increment() {
            count++;
        }
        
        public int getCount() {
            return count;
        }
    }
    
    // In main:
    Counter c = new Counter();
    c.increment();
    c.increment();
    c.increment();
    System.out.println(c.getCount());
    
    • A
      0
      Why not A: Each call to increment() increases count by 1. After 3 calls, count is 3, not 0.
    • B
      3Correct
    • C
      1
      Why not C: Three separate increment() calls are made. Each call increments the same instance variable.
    • D
      Compile error: count is private.
      Why not D: Private fields are accessible within the class. increment() and getCount() are methods in the same class, so they can access count.
    Explanation

    Three calls to increment() each add 1 to count, which starts at 0. After three increments, count = 3. getCount() returns the current value of count.

    Key takeaway

    Instance variables are shared across method calls on the same object. Each method call can modify the object's state.

  3. Question 3 · Easy

    Given the following class, which statement correctly accesses the name variable from OUTSIDE the class?

    public class Person {
        private String name;
        
        public Person(String n) {
            name = n;
        }
        
        public String getName() {
            return name;
        }
    }
    
    • A
      Person p = new Person("Alice"); System.out.println(p.name);
      Why not A: name is private. Accessing it directly from outside the class causes a compile error.
    • B
      Person p = new Person("Alice"); System.out.println(p.getName());Correct
    • C
      Person p = new Person("Alice"); System.out.println(Person.name);
      Why not C: name is an instance variable (not static). You cannot access it through the class name.
    • D
      Person p = new Person("Alice"); System.out.println(name);
      Why not D: name is not in scope outside the Person class. You must call the getter method on an instance.
    Explanation

    Private fields can only be accessed directly within the class. From outside, you must use the public getter getName(). This is encapsulation — hiding implementation details and providing controlled access.

    Key takeaway

    Private instance variables are not accessible outside the class. Use public getter methods to provide read access.

  4. Question 4 · Easy

    What is the output of the following code?

    public class Box {
        private int value;
        
        public Box(int v) {
            value = v;
        }
        
        public void doubleValue() {
            value = value * 2;
        }
        
        public int getValue() { return value; }
    }
    
    // In main:
    Box b1 = new Box(5);
    Box b2 = b1;
    b2.doubleValue();
    System.out.println(b1.getValue());
    
    • A
      5
      Why not A: b2 = b1 makes both variables refer to the SAME object. Calling b2.doubleValue() modifies the shared object, so b1.getValue() sees the change.
    • B
      10Correct
    • C
      20
      Why not C: doubleValue() is called only once. 5 * 2 = 10, not 20.
    • D
      Compile error
      Why not D: The code is valid. Assigning one object reference to another is legal in Java.
    Explanation

    b2 = b1 copies the reference, not the object. Both b1 and b2 point to the same Box object in memory. When b2.doubleValue() is called, the shared object's value changes from 5 to 10. b1.getValue() returns 10.

    Key takeaway

    Assigning an object reference copies the address, not the object. Both variables then point to the same object.

  5. Question 5 · Easy

    What is the output of the following code?

    public class MathHelper {
        private int x;
        
        public MathHelper(int x) {
            this.x = x;
        }
        
        public int triple() {
            return x * 3;
        }
        
        public static int square(int n) {
            return n * n;
        }
    }
    
    // In main:
    MathHelper m = new MathHelper(4);
    System.out.println(m.triple());
    System.out.println(MathHelper.square(5));
    
    • A
      12\n25Correct
    • B
      12\n20
      Why not B: square(5) returns 55=25, not 54=20. The static method receives 5 as its argument.
    • C
      16\n25
      Why not C: triple() returns x3 = 43 = 12, not 4*4=16 (that would be square).
    • D
      Compile error: cannot call static method on instance.
      Why not D: MathHelper.square(5) is the correct way to call a static method — via the class name. This is valid Java.
    Explanation

    m.triple() uses the instance variable x=4 and returns 43=12. MathHelper.square(5) is a static method called on the class (not an instance) and returns 55=25. this.x = x in the constructor uses this to distinguish the instance variable from the parameter.

    Key takeaway

    Static methods belong to the class and are called via the class name. Instance methods belong to an object and are called via a reference.

  6. Question 6 · Easy

    Which of the following best explains the purpose of the this keyword in the following constructor?

    public class Point {
        private double x;
        private double y;
        
        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
    
    • A
      this calls the parent class constructor.
      Why not A: super() (not this) calls the parent class constructor. this refers to the current object.
    • B
      this.x refers to the instance variable x, distinguishing it from the parameter x.Correct
    • C
      this is required whenever assigning values in a constructor.
      Why not C: this is only needed when a parameter name shadows an instance variable. If they had different names (e.g., parameter xVal), this would be optional.
    • D
      this.x = x assigns the instance variable to the parameter.
      Why not D: The direction is reversed: this.x = x assigns the parameter value (x on the right) TO the instance variable (this.x on the left).
    Explanation

    When a constructor parameter has the same name as an instance variable, this.x refers to the instance variable while x alone refers to the parameter. this.x = x assigns the parameter's value to the instance variable.

    Key takeaway

    `this` refers to the current object. Use `this.field` to distinguish instance variables from parameters with the same name.

  7. Question 7 · Easy

    What is the output of the following code?

    public class Student {
        private String name;
        private int grade;
        
        public Student(String name, int grade) {
            this.name = name;
            this.grade = grade;
        }
        
        public void setGrade(int grade) {
            if (grade >= 0 && grade <= 100) {
                this.grade = grade;
            }
        }
        
        public int getGrade() { return grade; }
    }
    
    // In main:
    Student s = new Student("Ali", 85);
    s.setGrade(110);
    System.out.println(s.getGrade());
    
    • A
      110
      Why not A: The setter validates the input. 110 is outside 0–100, so the assignment is skipped and grade stays at 85.
    • B
      85Correct
    • C
      0
      Why not C: The setter only ignores invalid input; it does not reset the grade to 0. The grade retains its previous value of 85.
    • D
      Compile error
      Why not D: This is valid Java. The setter is a standard validation pattern where invalid inputs are ignored.
    Explanation

    The setGrade method validates the new grade: 110 is NOT in the range [0, 100], so the body of the if statement does NOT execute. The instance variable grade remains unchanged at 85.

    Key takeaway

    Setters can validate input before modifying instance variables — a key benefit of encapsulation.

  8. Question 8 · Easy

    What is the output of the following code?

    public class Accumulator {
        private static int total = 0;
        private int value;
        
        public Accumulator(int v) {
            value = v;
            total += v;
        }
        
        public static int getTotal() { return total; }
    }
    
    // In main:
    Accumulator a1 = new Accumulator(10);
    Accumulator a2 = new Accumulator(20);
    Accumulator a3 = new Accumulator(5);
    System.out.println(Accumulator.getTotal());
    
    • A
      5
      Why not A: total is static and shared among all instances. Each constructor call adds to the same total variable. 10+20+5=35.
    • B
      35Correct
    • C
      10
      Why not C: Only the last constructor's value would give 5, and only the first would give 10. total accumulates all three.
    • D
      0
      Why not D: total starts at 0 but is modified by each constructor call. After creating a1, a2, a3, total = 10+20+5 = 35.
    Explanation

    total is a static variable shared by all instances of the class. Each constructor call adds to total: 0+10=10, 10+20=30, 30+5=35. getTotal() returns 35.

    Key takeaway

    Static variables are shared across all instances. Each object creation that modifies a static variable affects all instances.

  9. Question 9 · Easy

    What is the output of the following code?

    public class Thing {
        private int x;
        
        public Thing() {
            x = 10;
        }
        
        public Thing(int x) {
            this.x = x;
        }
        
        public int getX() { return x; }
    }
    
    // In main:
    Thing a = new Thing();
    Thing b = new Thing(7);
    System.out.println(a.getX() + b.getX());
    
    • A
      17Correct
    • B
      7
      Why not B: a uses the no-arg constructor, setting x=10. 10 + 7 = 17, not just 7.
    • C
      10
      Why not C: Both objects are created. a.getX() = 10, b.getX() = 7, and 10+7 = 17.
    • D
      Compile error: duplicate constructor definitions.
      Why not D: Java allows constructor overloading — multiple constructors with different parameter lists. This is valid.
    Explanation

    Constructor overloading allows multiple constructors with different signatures. new Thing() calls the no-arg constructor, setting x=10. new Thing(7) calls the one-arg constructor, setting x=7. Sum = 10+7 = 17.

    Key takeaway

    A class can have multiple constructors (overloading) as long as their parameter lists differ in type or number.

  10. Question 10 · Medium

    Given the following class definition, which of the following correctly modifies the balance from a test class BankTester?

    public class BankAccount {
        private double balance;
        
        public BankAccount(double initial) {
            balance = initial;
        }
        
        public void deposit(double amount) {
            if (amount > 0) balance += amount;
        }
        
        public double getBalance() { return balance; }
    }
    
    • A
      BankAccount acct = new BankAccount(100); acct.balance = 200;
      Why not A: balance is private. Direct field access from outside the class causes a compile error.
    • B
      BankAccount acct = new BankAccount(100); acct.deposit(50);Correct
    • C
      BankAccount.balance = 200;
      Why not C: balance is an instance variable, not static. It cannot be accessed via the class name.
    • D
      BankAccount acct = new BankAccount(100); acct.deposit(-50);
      Why not D: The deposit method validates that amount > 0. A negative deposit (-50) is ignored; balance stays at 100.
    Explanation

    Option B correctly calls the public deposit method with a positive amount. Private fields must be modified through public methods. Option A fails because balance is private. Option D fails because -50 does not satisfy amount > 0.

    Key takeaway

    Encapsulation: private fields are modified only through public methods. This allows the class to enforce valid state.

  11. Question 11 · Medium

    What is the output of the following code?

    public class Counter {
        private int count;
        
        public Counter(int start) {
            count = start;
        }
        
        public Counter add(int n) {
            count += n;
            return this;
        }
        
        public int getCount() { return count; }
    }
    
    // In main:
    Counter c = new Counter(0);
    System.out.println(c.add(3).add(4).getCount());
    
    • A
      3
      Why not A: add(3) returns this (the same Counter), then add(4) adds 4 more to the same object. Total = 3+4 = 7.
    • B
      7Correct
    • C
      Compile error: add returns Counter, not void.
      Why not C: Returning this from a method enables method chaining. The code is valid and commonly used in fluent-style APIs.
    • D
      4
      Why not D: Method chaining: c.add(3) modifies count to 3 and returns the same Counter. .add(4) then adds 4 to get 7.
    Explanation

    add(3) adds 3 to count (now 3) and returns this (the same Counter object). .add(4) adds 4 to count (now 7) and returns this. .getCount() returns 7. Returning this enables fluent method chaining.

    Key takeaway

    Returning `this` from a method enables method chaining — each call operates on the same object.

  12. Question 12 · Medium

    What is printed by the following code?

    public class Temp {
        private double celsius;
        
        public Temp(double c) { celsius = c; }
        
        public double toFahrenheit() {
            return celsius * 9 / 5 + 32;
        }
        
        public String toString() {
            return celsius + "C";
        }
    }
    
    // In main:
    Temp t = new Temp(100);
    System.out.println(t);
    System.out.println(t.toFahrenheit());
    
    • A
      Temp@[hashcode]\n212.0
      Why not A: The class overrides toString(), so println(t) calls the overridden version and prints "100.0C", not the default hash.
    • B
      100.0C\n212.0Correct
    • C
      100C\n212.0
      Why not C: The constructor takes a double (100 is widened to 100.0). toString() returns celsius + "C" = "100.0C" (double concatenated with String).
    • D
      100.0C\n180.0
      Why not D: The formula is 100*9/5+32 = 900/5+32 = 180+32 = 212. The +32 is part of the Fahrenheit conversion.
    Explanation

    Overriding toString() gives objects a custom String representation. println(t) implicitly calls t.toString() which returns "100.0C" (celsius is stored as 100.0). toFahrenheit() = 100*9/5+32 = 180+32 = 212.0.

    Key takeaway

    Overriding `toString()` customizes how an object is printed. `println(obj)` calls `toString()` automatically.