> For the complete documentation index, see [llms.txt](https://easy-draw.joemazzone.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://easy-draw.joemazzone.net/java-curriculum/unit-4-methods-and-classes-to-abstract-drawings.md).

# Unit 4: Methods and Classes to Abstract Drawings

In this unit students write their own **methods** and **classes**. A `drawTree()` method hides the details of drawing a tree. A `Tree` class goes further: each tree becomes an object with its own instance variables and methods, just like the Easy Draw shapes students have been using all year.

{% hint style="info" %}
**Teacher notes**

* **Time:** 9 class periods: 4 lessons (1 class each) and 5 classes for the unit project
* **AP Computer Science A:** Writing Classes (instance variables, constructors, methods, accessors and mutators, `this`, `static`, encapsulation, and scope).
* **Before this unit:** students have finished [Unit 3: Iteration and Drawings](/java-curriculum/unit-3-iteration-and-drawings.md).
* **Files:** projects now have three files in one folder: `EasyDraw.java`, `Main.java`, and the student's class, like `Tree.java`. Compile with `javac *.java`.
  {% endhint %}

## Learning Objectives

Students will be able to:

1. Write `static` methods with parameters to draw reusable pictures.
2. Write methods that return a value.
3. Write a class with `private` instance variables, a constructor, accessor methods, and mutator methods.
4. Use `this` to refer to the current object's instance variables.
5. Create many objects from their own class and store them in an array.
6. Explain how classes **abstract** (hide) details so a program is easier to read and change.

## Lesson 4.1: Static Methods That Draw

```java
public class Main {
    public static void main(String[] args) {
        EasyDraw.loadCanvas("lightblue");

        drawTree(100, 450, 120);
        drawTree(300, 400, 200);
        drawTree(500, 470, 80);

        EasyDraw.end();
    }

    /** Draws a tree with the bottom of its leaves at (x, y). */
    public static void drawTree(double x, double y, double size) {
        EasyDraw.Rectangle trunk = new EasyDraw.Rectangle(x - size / 8, y, size / 4, size / 2);
        trunk.setColor("saddlebrown");

        EasyDraw.Circle leaves = new EasyDraw.Circle(x, y - size / 4, size / 2);
        leaves.setColor("forestgreen");
    }
}
```

Vocabulary: **method header**, **parameters**, **arguments**, **method call**.

**Practice:**

1. Use a loop in `main` to call `drawTree()` 6 times across the canvas.
2. Add a `String color` parameter so each tree's leaves can be a different color.

## Lesson 4.2: Methods That Return Values

```java
public class Main {
    public static void main(String[] args) {
        EasyDraw.loadCanvas();

        EasyDraw.Circle a = new EasyDraw.Circle(200, 300, 60);
        EasyDraw.Circle b = new EasyDraw.Circle(330, 300, 80);

        if (touching(a, b)) {
            a.setColor("red");
            b.setColor("red");
        }

        EasyDraw.end();
    }

    /** Returns true when two circles overlap. */
    public static boolean touching(EasyDraw.Circle c1, EasyDraw.Circle c2) {
        double dx = c1.getCenterX() - c2.getCenterX();
        double dy = c1.getCenterY() - c2.getCenterY();
        double distance = Math.sqrt(dx * dx + dy * dy);
        return distance < c1.getRadius() + c2.getRadius();
    }
}
```

**Practice:** Move circle `b` to (400, 300). Predict the color, then run it.

## Lesson 4.3: Writing a Class

`drawTree()` draws a tree, but afterward we cannot move it or change it. A `Tree` **class** keeps references to its shapes in **instance variables**, so every `Tree` object can be changed later.

`Tree.java`:

```java
public class Tree {
    private double x;
    private double y;
    private double size;
    private EasyDraw.Rectangle trunk;
    private EasyDraw.Circle leaves;

    /** Creates a tree with the bottom of its leaves at (x, y). */
    public Tree(double x, double y, double size) {
        this.x = x;
        this.y = y;
        this.size = size;

        trunk = new EasyDraw.Rectangle(x - size / 8, y, size / 4, size / 2);
        trunk.setColor("saddlebrown");

        leaves = new EasyDraw.Circle(x, y - size / 4, size / 2);
        leaves.setColor("forestgreen");
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    /** Moves the whole tree by dx and dy. */
    public void move(double dx, double dy) {
        x = x + dx;
        y = y + dy;
        trunk.setXY(x - size / 8, y);
        leaves.setCenter(x, y - size / 4);
    }

    public void setLeafColor(String color) {
        leaves.setColor(color);
    }
}
```

`Main.java`:

```java
public class Main {
    public static void main(String[] args) {
        EasyDraw.loadCanvas("lightblue");

        Tree oak = new Tree(150, 400, 150);
        Tree maple = new Tree(400, 400, 200);

        maple.setLeafColor("orangered");
        oak.move(-50, 50);

        EasyDraw.end();
    }
}
```

Walk through the parts of the class:

* **Instance variables** (`x`, `y`, `size`, `trunk`, `leaves`) - every `Tree` object has its own copy. They are `private`, so only `Tree`'s own methods can change them. This is **encapsulation**.
* **Constructor** - runs when we write `new Tree(...)`. `this.x = x;` copies the parameter `x` into the instance variable `x`.
* **Accessor methods** (`getX()`, `getY()`) return information.
* **Mutator methods** (`move()`, `setLeafColor()`) change the object.

**Discussion:** `Main` does not know a tree is made of a rectangle and a circle. If we changed the leaves to a triangle, would `Main` need to change? This is **abstraction**.

**Practice:**

1. Add a `grow(double amount)` method that makes the tree bigger. (Hint: change `size`, then update both shapes with their setters.)
2. Add a `toString()` method that returns something like `"Tree at (150.0, 400.0)"`.

## Lesson 4.4: Objects That Respond to Events

A class can set up its own event handlers in its constructor. Each object then responds on its own.

`Balloon.java`:

```java
public class Balloon {
    private static int popped = 0;

    private EasyDraw.Circle body;
    private EasyDraw.Line string;

    public Balloon(double x, double y, String color) {
        string = new EasyDraw.Line(x, y + 40, x, y + 140);
        string.setThickness(2);
        body = new EasyDraw.Circle(x, y, 40);
        body.setColor(color);

        body.eventSetup("<Button-1>", event -> pop());
    }

    public void pop() {
        body.erase();
        string.erase();
        popped++;
        System.out.println("Popped " + popped + " balloons!");
    }

    public static int getPopped() {
        return popped;
    }
}
```

`Main.java`:

```java
public class Main {
    public static void main(String[] args) {
        EasyDraw.loadCanvas();

        String[] colors = {"red", "orange", "gold", "green", "blue", "purple"};
        Balloon[] balloons = new Balloon[colors.length];

        for (int i = 0; i < balloons.length; i++) {
            balloons[i] = new Balloon(75 + i * 90, 250, colors[i]);
        }

        EasyDraw.end();
    }
}
```

**Discussion:** `popped` is `static`, but `body` is not. What is the difference? (There is one `popped` shared by every balloon, but each balloon has its own `body`.)

## Unit Project: My Own Class

Students design a class for something that can be drawn and changed, then write a program that uses many objects of that class. Ideas: `Car`, `Fish`, `House`, `Robot`, `Monster`, `Flower`, `Spaceship`.

**Requirements:**

* A class in its own file with at least 3 `private` instance variables, including at least 2 Easy Draw shapes.
* A constructor with parameters that uses `this`.
* At least 2 accessor methods and at least 2 mutator methods (one should move the whole drawing).
* A `toString()` method.
* At least one `static` variable or method in the class.
* `Main` creates at least 5 objects, stored in an array, and uses a loop to call a method on each one.
* At least one event (click or key) changes the objects.
* A short written explanation of how the class **abstracts** the drawing.

| Category     | 4 - Exceeds                                     | 3 - Meets                                        | 2 - Approaching                   | 1 - Beginning          |
| ------------ | ----------------------------------------------- | ------------------------------------------------ | --------------------------------- | ---------------------- |
| Class design | Well-encapsulated class with meaningful methods | All required variables, constructor, and methods | Missing some required parts       | Class does not compile |
| Objects      | Many objects interact in interesting ways       | 5+ objects in an array, changed with a loop      | Objects not stored in an array    | One object             |
| Events       | Objects respond to several kinds of events      | At least one event changes the objects           | Event attempted but does not work | No events              |
| Code quality | Clear names, Javadoc comments on every method   | Comments explain each method                     | Few comments                      | Hard to read           |
| Explanation  | Clearly explains abstraction and encapsulation  | Explains how the class hides details             | Explanation is unclear            | Missing                |
