# Lesson 9 - More OOP

## DIY  - Creating Fib Class (10 minutes)

![Fibonacci Sequence using LMC | 101 Computing](https://www.101computing.net/wp/wp-content/uploads/fibonacci-sequence.png)

create a `Fib` class that can run the following code:

```java
Fib fib = new Fib();
fib.next(2);
System.out.println(fib);
System.out.println(fib.next(3));
System.out.println(fib.next().next());


Fib fib2 = new Fib(7).next().prev();
System.out.println(fib2);

System.out.println("are fibs equal? " + (fib.equals(fib2) ? "yes" : "no"));
```

```
Fib(2) = 3
Fib(5) = 13
Fib(7) = 34
Fib(7) = 34
are fibs equal? yes
```

### Solution

{% tabs %}
{% tab title="Main.java" %}

```java
public class Main {
    public static void main(String[] args) {
        Fib fib = new Fib();
        fib.next(2);
        System.out.println(fib);
        System.out.println(fib.next(3));
        System.out.println(fib.next().next());

        Fib fib2 = new Fib(6).next();
        System.out.println(fib2);

        System.out.println("are fibs equal? " + (fib.equals(fib2) ? "yes" : "no"));
    }
}
```

{% endtab %}

{% tab title="Fib.java" %}

```java
public class Fib {
    private int a;
    private int b;
    private int n;

    Fib() {
        this(0); // call: Fib(int num),  don't increment
    }

    Fib(int num) {
        a = 0;
        b = 1;
        n = 0;

        next(num);
    }

    Fib next() {
        return next(1);
    }

    Fib next(int num) {
        while (num > 0){
            int temp = a;
            a = b;
            b += temp;
            --num;
            ++n;
        }
        return this;
    }

    Fib prev() {
        return prev(1);
    }

    Fib prev(int num) {
        while (num > 0 && n > 1){
            int temp = a;
            a = b - a;
            b = temp;
            --num;
            --n;
        }
        return this;
    }

    @Override
    public String toString() {
        return "Fib(" + n + ") = " + (a+b) ;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Fib fib = (Fib) o;
        return n == fib.n;
    }
}
```

{% endtab %}
{% endtabs %}

```
Fib(2) = 3
Fib(5) = 13
Fib(7) = 34
Fib(7) = 34
are fibs equal? yes
```

##

## Creating an IntList

![](https://i.ibb.co/BqDCxY2/IntList.jpg)

{% tabs %}
{% tab title="Main.java" %}

```java
public class Main {
    public static void main(String[] args) {
        IntList list = new IntList(4, 10);
        list.add(20).add(30);

        System.out.println(list);

        for (int i = 0; i < list.length() ; i++)
            System.out.print(list.get(i) + " ,");

        System.out.println("\n======= Equals =======\n");
        IntList new_list = new IntList(list); // Calls copy constructor

        System.out.println("new_list: " + new_list.toString());
        System.out.println("are the list the same: " + new_list.equals(list));

        new_list.add(100);
        System.out.println("new_list: " + new_list);
        System.out.println("are the list the same: " + new_list.equals(list));

        new_list.remove_index(6);
        System.out.println("new_list: " + new_list);
        System.out.println("are the list the same: " + new_list.equals(list));
    }
}
```

{% endtab %}

{% tab title="IntList .java" %}

```java
import java.util.Arrays;

public class IntList {
    private int size = 0; // shouldn't be public
    private static final int DEFAULT_CAPACITY = 10;
    private int[] elements;

    // ===== Constructors =====

    //default constructor
    public IntList() {
        elements = new int[DEFAULT_CAPACITY]; // or: this(DEFAULT_CAPACITY)
    }

    // Create int list with x elements, no values
    public IntList(int size) {
        elements = new int[size];
    }

    // Create int list with x elements, no values
    public IntList(int size, int num_2_fil) {
        elements = new int[size];
        this.size = size;
        Arrays.fill(elements, num_2_fil);
    }

    // copy constructor
    public IntList(IntList other) {
        size = other.size;
        elements = new int[size];

        //deep copy, could also use:
        //elements = Arrays.copyOf(other.elements, other.size);
        for (int i = 0; i < other.length(); i++)
            elements[i] = other.elements[i]; // or other.add(elements[i])
    }


    // ===== methods =====

    //add elemements
    public IntList add(int elem) {
        if (size == elements.length) {
            increaseCapacity();
        }
        elements[size++] = elem;

        return this; //<--------- show without returning this
    }

    //add elemements
    public IntList add(int elem, int amount) {
        while (amount>=0){
            if (size == elements.length)
                increaseCapacity();

            elements[size++] = elem;
            --amount;
        }

        return this; //<--------- show without returning this
    }

    //double the capacity
    private void increaseCapacity() {
        int newSize = elements.length * 2;
        elements = Arrays.copyOf(elements, newSize);
    }

    //get index
    public int get(int i) {
        if (i>= size || i <0)
            return -1;

        return elements[i];
    }

    public int length() {
        return size;
    }


    //remove index
    public int remove_index(int index) {
        int removed_elem;

        if (index>= size || index <=0)
            return -1;

        removed_elem = elements[index];
        size--;

        //end of IntList
        if (index==elements.length-1){
            elements[index] = 0;
        }

        for (int i = index; i < elements.length; i++)
            if (i+1<elements.length)
                elements[i] = elements[i+1];

        return removed_elem;
    }


    // ===== toString & equals =====

    @Override
    public String toString() {
        StringBuilder elems = new StringBuilder("[");
        for (int i = 0; i < size-1; i++)
            elems.append(elements[i] + ", ");
        elems.append(elements[size-1] + "]");


        return "IntList{" +
                "size=" + size +
                ", capacity=" + elements.length +
                ", elements=" + elems.toString() +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        IntList intList = (IntList) o;

        if (size == intList.size){
            for (int i = 0; i < size; i++)
                if (elements[i] != intList.get(i))
                    return false;

            return true;
        }
        return false;

//        return size == intList.size
//                && Arrays.equals(elements, intList.elements);
    }
}
```

{% endtab %}
{% endtabs %}

```
IntList{size=6, capacity=8, elements=[10, 10, 10, 10, 20, 30]}
10 ,10 ,10 ,10 ,20 ,30 ,

======= Equals =======
new_list: IntList{size=6, capacity=6, elements=[10, 10, 10, 10, 20, 30]}
are the list the same: true
new_list: IntList{size=7, capacity=12, elements=[10, 10, 10, 10, 20, 30, 100]}
are the list the same: false
new_list: IntList{size=6, capacity=12, elements=[10, 10, 10, 10, 20, 30]}
are the list the same: true
```

another example

```java
public class Main {
    public static void main(String[] args) {
        IntList list = new IntList(4, 10).add(20);
        System.out.println(list);

        list.add(100,4).remove_index(4);
        System.out.println(list);
    }
}
```

```
IntList{size=5, capacity=8, elements=[10, 10, 10, 10, 20]}
IntList{size=9, capacity=16, elements=[10, 10, 10, 10, 100, 100, 100, 100, 100]}
```

##

## Polygon (Point list)

![Source: https://www.geogebra.org/m/amtvtmvv](https://2498830366-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MVGLlEB8nZRYjtdyfF8%2F-Ma32OKWU3-OdL4zxs-Z%2F-Ma32ScbWq-sYEIdwUkx%2Fimage.png?alt=media\&token=7da8dcdd-bbaa-47d0-96b9-fb6912601229)

![polygon-list](https://i.ibb.co/d0js9KG/polygon-list.jpg)

Lets change a **few** properties of our `IntList` and create a `PointList`

we will add a few fields

* Color color
* String name

and a method to convert the the **x** and y to a list of double

* `double[] convert2DoubleArray(String x_or_y)`

{% tabs %}
{% tab title="Main" %}

```java
public class Main {
    public static void main(String[] args) {
        Polygon list = new Polygon(3, new Point(1, 2)).add(new Point(30, 40));
        System.out.println(list);

        list.add(new Point(-100, -100),3).remove_index(4);
        System.out.println(list);

        Polygon new_list = new Polygon(list);
        System.out.println("are the Polygons the same? " + list.equals(new_list));
        list.remove_index(3);
        System.out.println("are the Polygons the same? " + list.equals(new_list));

    }
}
```

{% endtab %}

{% tab title="Polygon " %}

```java
import java.util.Arrays;

import java.awt.*;
import java.util.Arrays;

public class Polygon {
    private int size = 0; // shouldn't be public
    private static final int DEFAULT_CAPACITY = 10;
    private Point[] elements;
    private Color color;
    private String name = new String("");

    // ===== Constructors =====

    //default constructor
    public Polygon() {
        this(DEFAULT_CAPACITY); //call Polygon(int size);
    }

    // Create Polygon with x elements, no values
    public Polygon(int size) {
        elements = new Point[size];
        setColor(0,0,255);
    }

    // Create int Polygon with x elements, no values
    public Polygon(int size, Point point_2_fil) {
        elements = new Point[size];
        this.size = size;
        Arrays.fill(elements, point_2_fil);
        setColor(0,0,255);
    }

    // copy constructor
    public Polygon(Polygon other) {
        size = other.size;
        elements = new Point[size];
        color = other.color;

        for (int i = 0; i < other.length(); i++)
            elements[i] = other.elements[i]; // or other.add(elements[i])
    }


    // ===== methods =====

    private double[] convert2DoubleArray(String x_or_y) {
        double[] list = new double[elements.length];

        switch (x_or_y) {
            case "x":
                for (int i = 0; i < size; i++)
                    list[i] = elements[i].getX();
                return list;
            //break;
            case "y":
                for (int i = 0; i < size; i++)
                    list[i] = elements[i].getY();
                return list;
            default:
                return new double[]{0., 0.};
        }
    }

    public void setColor(int r, int g, int b) {
        this.color = new Color(r, g, b);
    }

    public void draw() {
        StdDraw.setPenColor(color);
        StdDraw.filledPolygon(convert2DoubleArray("x"), convert2DoubleArray("y"));
    }

    //add elemements
    public Polygon add(Point elem) {
        if (size == elements.length) {
            increaseCapacity();
        }
        elements[size++] = elem;

        return this; //<--------- show without returning this
    }

    //add elemements
    public Polygon add(Point elem, int amount) {
        while (amount>=0){
            if (size == elements.length)
                increaseCapacity();

            elements[size++] = elem;
            --amount;
        }

        return this; //<--------- show without returning this
    }

    //double the capacity
    private void increaseCapacity() {
        int newSize = elements.length * 2;
        elements = Arrays.copyOf(elements, newSize);
    }

    //get index
    public Point get(int i) {
        if (i>= size || i <0)
            return new Point();

        return elements[i];
    }

    public int length() {
        return size;
    }


    //remove index
    public Point remove_index(int index) {
        Point removed_elem;

        if (index>= size || index <=0)
            return new Point();

        removed_elem = elements[index];
        size--;

        //end of Polygon
        if (index==elements.length-1){
            elements[index] = new Point();
        }

        for (int i = index; i < elements.length; i++)
            if (i+1<elements.length)
                elements[i] = elements[i+1];

        return removed_elem;
    }


    // ===== toString & equals =====

    @Override
    public String toString() {
        StringBuilder elems = new StringBuilder("[");
        for (int i = 0; i < size-1; i++)
            elems.append(elements[i] + ", ");
        elems.append(elements[size-1] + "]");


        return "Polygon{" +
                "size=" + size +
                ", capacity=" + elements.length +
                ", elements=" + elems.toString() +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Polygon polygon = (Polygon) o;

        if (size == polygon.size){
            for (int i = 0; i < size; i++)
                if (elements[i] != polygon.get(i))
                    return false;

            return true;
        }
        return false;

    }
}
```

{% endtab %}

{% tab title="Point.java" %}

```java
class Point {
    private double x, y;

    //=== constructors ===

    //default constructor
    Point() {
        x =0;
        y = 0;
    }

    Point(double new_x, double y) {
        x = new_x;
        this.y = y;
    }

    //copy constructor
    Point(Point p) {
        x = p.x; // Since this is the same class I can access without getter/setter
        y = p.y;
    }

    //=== static methods ===
    public static double distance(Point a, Point b) {
        double dist = Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y, 2);
        return Math.sqrt(dist);
    }



    //=== getters and setters ===
    public double getX() {
        return x;
    }

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

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public String toString() {
        return "Point {" + " x=" + x + ", y=" + y + " }";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return Double.compare(point.x, x) == 0 && Double.compare(point.y, y) == 0;
    }
}
```

{% endtab %}
{% endtabs %}

```
PointList{size=4, capacity=6, elements=[Point { x=1.0, y=2.0 }, Point { x=1.0, y=2.0 }, Point { x=1.0, y=2.0 }, Point { x=30.0, y=40.0 }]}

PointList{size=7, capacity=12, elements=[Point { x=1.0, y=2.0 }, Point { x=1.0, y=2.0 }, Point { x=1.0, y=2.0 }, Point { x=30.0, y=40.0 }, Point { x=-100.0, y=-100.0 }, Point { x=-100.0, y=-100.0 }, Point { x=-100.0, y=-100.0 }]}

are the Polygons the same? true
are the Polygons the same? false
```

## Drawing the polygon

![](https://i.ibb.co/qjdmCdv/polygon1.jpg)

Lets now draw a Polygon (Point list with at least 3 points + the first point to close the loop)

The points in the polygon are (`x[i]`, `y[i]`). For example, the following code fragment draws a filled diamond with vertices (0.1, 0.2), (0.2, 0.3), (0.3, 0.2), and (0.2, 0.1):

```
   double[] x = { 0.1, 0.2, 0.3, 0.2 };
   double[] y = { 0.2, 0.3, 0.2, 0.1 };
   StdDraw.filledPolygon(x, y);
```

so we need to add the following function to `Polygon`

```java
private double[] convert2DoubleArray(String x_or_y) {
        double[] list = new double[elements.length];

        switch (x_or_y) {
            case "x":
                for (int i = 0; i < size; i++)
                    list[i] = elements[i].getX();
                return list;
            //break;
            case "y":
                for (int i = 0; i < size; i++)
                    list[i] = elements[i].getY();
                return list;
            default:
                return new double[]{0., 0.};
        }
    }
```

```java
public class Main {
    public static void main(String[] args) {
        Polygon polygon1 = new Polygon();
        polygon1.add(new Point(20,20));
        polygon1.add(new Point(80,20));
        polygon1.add(new Point(50,70));
        polygon1.add(new Point(20,20));

        Polygon polygon2 = new Polygon();
        polygon2.setColor(0,255,0);
        polygon2.add(new Point(80,20));
        polygon2.add(new Point(90,40));
        polygon2.add(new Point(50,70));
        polygon2.add(new Point(80,20));


        StdDraw.setXscale(0, 100);
        StdDraw.setYscale(0, 100);
        polygon1.draw();
        polygon2.draw();
    }
}
```

![](https://i.ibb.co/37ynhgC/polygon-explanation.jpg)

or

```java
public class Main {
    public static void main(String[] args) {
        Polygon[] polygons = new Polygon[3];

        polygons[0] = new Polygon();
        polygons[0].add(new Point(229,153));
        polygons[0].add(new Point(160,218));
        polygons[0].add(new Point(177,325));
        polygons[0].add(new Point(249,268));
        polygons[0].add(new Point(229,153));


        polygons[1] = new Polygon();
        polygons[1].setColor(0,255,0);
        polygons[1].add(new Point(249,268));
        polygons[1].add(new Point(177,325));
        polygons[1].add(new Point(269,336));
        polygons[1].add(new Point(349,283));
        polygons[1].add(new Point(249,268));

        polygons[2] = new Polygon().setName("redPolygon");
        polygons[2].setColor(255,0,0);
        polygons[2].add(new Point(349,283));
        polygons[2].add(new Point(328,182));
        polygons[2].add(new Point(229,153));
        polygons[2].add(new Point(249,268));
        polygons[2].add(new Point(349,283));


        StdDraw.setXscale(0, 500);
        StdDraw.setYscale(0, 500);

        for (int i = 0; i < polygons.length; i++) {
            polygons[i].draw();
            System.out.println(polygons[i]);
        }

    }
}
```

```
polygon_1: Polygon{num of points: 5, capacity=10, elements=[Point { x=229.0, y=153.0 }, Point { x=160.0, y=218.0 }, Point { x=177.0, y=325.0 }, Point { x=249.0, y=268.0 }, Point { x=229.0, y=153.0 }]}

polygon_2: Polygon{num of points: 5, capacity=10, elements=[Point { x=249.0, y=268.0 }, Point { x=177.0, y=325.0 }, Point { x=269.0, y=336.0 }, Point { x=349.0, y=283.0 }, Point { x=249.0, y=268.0 }]}

redPolygon: Polygon{num of points: 5, capacity=10, elements=[Point { x=349.0, y=283.0 }, Point { x=328.0, y=182.0 }, Point { x=229.0, y=153.0 }, Point { x=249.0, y=268.0 }, Point { x=349.0, y=283.0 }]}
```

![](https://i.ibb.co/mt3bZ3K/3dCube.jpg)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nissan-goldberg.gitbook.io/java101/lesson-8-oop/m.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
