CSA Blog

Ian Wu

Unit 4.2 - For Loops

4.1 While Loop 4.2 For Loop 4.3 String Iteration 4.4 Nested Iteration Unit 4 HW Quiz

4.2 For Loops

Similar to while loops, for loops run until a condition is false. Format of for loop below:

for (int i = 0; i < 5; i++) {
    System.out.println(i);
}
0
1
2
3
4

Explanation

  • in the above for loop:
    • int i = 0 defines the iterating variable
    • i < 5 is the condition (once i < 5 is false, this loop breaks)
    • i++ is the incrementation of the iterating variable
    • System.out.println(i); is the body code that runs every time the loop iterates

For Each Loops:

  • Apart from iterating using an incrementing variable, you can also iterate through items in a list.

    Example of For Each loop below

int[] list = {1, 2, 3, 4, 5}; // any list
for (int item : list) { // for each item in the list, execute the body
    System.out.println(item); // body code
}
0
1
2
3
4
#python version
array=[1, 2, 3, 4, 5]
for i in array:
    print(i)

Explanation:

  • in the above loop:
    • int item : list - this line is saying that for each item in the list, execute code below
    • System.out.println(num); - this line is the body code.

Fun For Loop Hack:

Create a program that iterates through a list of numbers (int_list = {0, 4, 51, 83, 92, 10, 123, 145}) using both a for loop and a for each loop, then split the numbers in the list into even/odd lists, and output them.

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] int_list = {0, 4, 51, 83, 92, 10, 123, 145};
        int[] even = new int[4];
        int[] odd = new int[4];

        int evenIndex = 0;
        int oddIndex = 0;

        for (int item : int_list) {
            if (item % 2 == 0) {
                even[evenIndex] = item;
                evenIndex++;
            } else {
                odd[oddIndex] = item;
                oddIndex++;
            }
        }

        // Print the even and odd arrays
        System.out.println("Even numbers: " + Arrays.toString(even));
        System.out.println("Odd numbers: " + Arrays.toString(odd));
    }
}

2
15


Iteration: 0

Current Velocity: 2, 2

Unit 4.1 - While Loops

4.1 While Loop 4.2 For Loop 4.3 String Iteration 4.4 Nested Iteration Unit 4 HW Quiz

4.1 While Loops

While loops run until the given condition is false. Format of loop below.

int index = 0; // iterating value
while (index < 5) { // condition, if this is false, the loop terminates
    System.out.println(index); // body code
    index++; // iterates the iterating value
}
0
1
2
3
4
# Python Version
i=0
while (i<5):
    print(i)
    i+=1
0
1
2
3
4

Explanation

  • in the above while loop:
    • index is the incrementing variable
    • index < 5 is the condition (once index < 5 is false, this loop breaks)
    • System.out.println(i); is the body code that runs every time the loop iterates
    • index++; is incrementing the incrementing variable

Do While Loops:

  • This type of while loop runs the block inside the do{} statement once, then iterates through the loop
  • this ensures that the code runs at least once

Example of Do While loop below

int i = 0; // iterating value
do { // this makes sure the code runs at least once
    System.out.println(i); // body code
    i++; // iterates the iterating value
} while (i < 5); // condition, if this is false, loop terminates
0
1
2
3
4

Explanation:

  • in the above loop:
    • code inside of the do{} statement runs at least once, then keeps on running as long as the condition, i<5, is true.
    • similarly to the normal while loop, there is body code, and there is an incrementing variable

IMPORTANT:

  • While loops to not have to have an incrementing variable, for example, you can have a loop that iterates as long as there are items present in a list
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);

System.out.println(list + " before loop!!");
while (!list.isEmpty()) {
    System.out.println("Element: " + list.remove(0));
}
System.out.println(list + " after loop!!");
[10, 20, 30, 40] before loop!!
Element: 10
Element: 20
Element: 30
Element: 40
[] after loop!!

Fun While Loop Hack:

  • find and fix the missing increment in the while loop
int i = 0;
while (i < 5) {
    System.out.println(i);
    i += 1;
}
2
15


Iteration: 0

Current Velocity: 2, 2

Creating References Using Inheritance Hierarchies

Introduction to Inheritance 9.1/9.2 9.3/9.4 9.5 9.6 9.7 Hacks

Understanding Class Hierarchies

Class hierarchies in Java enable structured relationships between classes through inheritance. This concept is foundational to object-oriented programming and enhances code reusability and organization, which simplifies managing complex systems.

In a class hierarchy, a superclass can pass down properties and methods to its subclasses. This allows subclasses to inherit functionality while also being able to define or modify behaviors that are specific to themselves. This leads to a more manageable code structure and helps in maintaining code consistency.

Components of Class Hierarchies

  1. Superclass: The parent class from which properties and methods are inherited.
  2. Subclass: A child class that inherits from the superclass and can override or extend its functionality.
  3. Polymorphism: The ability to treat objects of different classes through a common interface, allowing for method overriding.

Example Hierarchy

public class Shape {
    protected String name;

    public Shape(String name) {
        this.name = name;
    }

    public double calc_area() {
        return 0.0;
    }

    public void print_shape() {
        System.out.println("Shape: " + name);
    }
}

Derived Class: Rectangle

Now, let’s create a Rectangle class that inherits from Shape.

public class Rectangle extends Shape {
    private int length;
    private int width;

    public Rectangle(String name, int length, int width) {
        super(name);
        this.length = length;
        this.width = width;
    }
}

class Circle extends Shape {
    @Override
    public double calc_area() {
        return length * width;
    }
}

Derived Class: Triangle

Next, let’s create a Triangle class that also inherits from Shape.

public class Triangle extends Shape {
    private int side1;
    private int side2;
    private int side3;

    public Triangle(String name, int s1, int s2, int s3) {
        super(name);
        this.side1 = s1;
        this.side2 = s2;
        this.side3 = s3;
    }
}

class Square extends Shape {
    @Override
    public String draw() {
        return "Drawing a square";
    }
}

Testing Our Classes

Let’s create instances of Rectangle and Triangle and call their methods.

}

public class Main {
    public static void main(String[] args) {
        Shape myCircle = new Circle();
        Shape mySquare = new Square();

        System.out.println(myCircle.draw()); // Outputs: Drawing a circle
        System.out.println(mySquare.draw()); // Outputs: Drawing a square
    }
}
Shape: Rectangle
Area of rectangle: 20.0
Shape: Triangle
Area of triangle: 6.0

In the example above, Shape acts as the superclass, while Circle and Square are subclasses that override the draw method to provide specific behavior. This demonstrates polymorphism, enabling us to reference subclasses using a superclass type and invoke the overridden methods dynamically at runtime. This is particularly powerful as it allows for flexibility in the code, facilitating easier changes and enhancements.

Benefits of Using Class Hierarchies

  1. Code Reusability: Common behaviors are defined in the superclass, significantly reducing code duplication and making it easier to maintain and update.
  2. Organized Structure: A clear hierarchical structure in your code aids in understanding the relationships between classes, making the codebase more intuitive and manageable.
  3. Polymorphism: Allows for dynamic method resolution, enabling methods to be invoked on objects of subclasses through references of the superclass type.

Practical Exercise: Popcorn Hack 1

Let’s implement the Triangle subclass to deepen your understanding. Below is a half-completed method for the Triangle class. Your task is to complete the draw method:

```java class Shape {
public String draw() {
    return "Drawing a shape";
} }

class Triangle extends Shape {
    @Override
    public String draw() {
        System.out.println("Drawing a triangle.")
    }
}

public class Main {
    public static void main(String[] args) {
        Shape myTriangle = new Triangle();
        System.out.println(myTriangle.draw()); // Should output: "Drawing a triangle."
    }
}
``` Make sure your implementation returns a unique string for the `Triangle` class. This exercise will help reinforce how subclasses can extend functionality.

Expanding Your Skills: Adding a Rectangle Class

Next, let’s implement the Rectangle subclass. Below is the basic setup for it. Your task is to implement the draw method for the Rectangle class:

```java class Rectangle extends Shape {
@Override
public String draw() {
    System.out.println("Drawing a rectangle.")
} }

public static void main(String[] args) {
    Shape myRectangle = new Rectangle();
    System.out.println(myRectangle.draw()); // Should output: "Drawing a rectangle."
}
``` Complete the `draw` method in `Rectangle`, ensuring it returns a unique string. This will reinforce how multiple subclasses can have distinct implementations of the same method, enhancing your understanding of class hierarchies.

Advanced Challenge: Area Calculation

Now, let’s enhance our Shape class to include an area calculation feature. Modify the Shape class to include an area method, and implement it in your subclasses. Below is a structure to help you get started:

```java class Shape {
public String draw() {
    return "Drawing a shape";
}
public double area() {
    return 0; 
} }

class Circle extends Shape {
    @Override
    public double area() {
        return this.radius * this.radius * Math.PI
    }
}

class Square extends Shape {
    @Override
    public double area() {
        return this.side * this.side
    }
}
// Implement for Triangle and Rectangle as well
``` Ensure each subclass calculates and returns its area correctly. This will allow you to practice method overriding further and understand how different shapes can extend base functionalities.

Homework Hack

For your homework, create your own class hierarchy for shapes. You should have a base class called Shape with subclasses Triangle, Rectangle, and Hexagon. Each subclass should implement a method called draw(), returning a unique string for each shape type.

- `Triangle`: "Drawing a triangle."

- `Rectangle`: "Drawing a rectangle."

- `Hexagon`: "Drawing a hexagon."

Make sure to demonstrate polymorphism by creating an array of Shape types and iterating through it to call the draw() method. This will reinforce your understanding of class hierarchies and method overriding.

public class Shape {
    public abstract String draw();
}

class Triangle extends Shape {
    @Override
    public String draw() {
        return "Drawing a triangle.";
    }
}

class Rectangle extends Shape {
    @Override
    public String draw() {
        return "Drawing a rectangle.";
    }
}

class Hexagon extends Shape {
    @Override
    public String draw() {
        return "Drawing a hexagon.";
    }
}

Shape[] shapes = {new Triangle(), new Rectangle(), new Hexagon()};

for (Shape shape : shapes) {
    System.out.println(shape.draw());
}
Drawing a triangle.
Drawing a rectangle.
Drawing a hexagon.