---
marp: true
title: 23 March 2021
theme: default
paginate: true
---
# <!-- fit --> CS 199 EMP

### Hosted by Jackie Chan and Akhila Ashokan

**Topics:** Anonymous Classes, Iterables and Iterators, and MORE on Interfaces 

---

# Today's Learning Objectives

- MORE on Interfaces

- Anonymous Classes 

- Iterables and Iterators 

Write code on the homepage or any playground on the site!
https://cs125.cs.illinois.edu/

Slides are on the course site!
https://cs199emp.netlify.app/

---

# Quick Refresher on Interfaces

- an Interface is a shared boundary across which two or more separate components of a computer system exchange information
- Interfaces have to be implemented by a specific class
- They can't function on their own
- They use the keyword `implements`.
- You also have to implement all the methods the interface declares.

---

# Coding Problem 1: Interfaces (10 minutes)

Modify Player so that it implements DungeonMaster.
```java
public interface DungeonMaster {
  boolean canCreateDungeonInstance(); // should return true 
  int increaseHealth(); // should increase health points by one 
};

public class Player {
  private String userName;
  private int healthPoints;
  private String state;
  
  public Player(String name) {
    userName = name;
    state = "ALIVE";
    healthPoints = 100;
  }
  public String isAlive() {
    return state;
  }
}
```
---

# Coding Problem 2: Interfaces (10 minutes)

Implement the comparable interface for the class given below. If two users have the same name, they are equal. If they have different usernames, compare using the healthPoints.  

```java
public interface DungeonMaster {
  boolean canCreateDungeonInstance(); // should return true 
  int increaseHealth(); // should increase health points by one 
};
public class Player {
  private String userName;
  private int healthPoints;
  private String state;
  
  public Player(String name) {
    userName = name;
    state = "ALIVE";
    healthPoints = 100;
  }
}
```
---

# "A [Class] Has No Name"

We've seen *named* classes since the beginning on the semester. 

```java
Camera one = new Camera(); 
```

So, what's so special about anonymous classes? 
- No Name 
- Must **extend another class or implement an interface**
- created immediately, since they have no name and can't be named later 
- cannot provide a constructor
- can *capture* variables outside the scope of the anonymous class 

---

# Let's take a look at an anonymous class 

```java
public class Camera {
  public String getType() {
    return "Nikon";
  }
}
Camera basic = new Camera(); 
// anonymous class that extends the Camera class 
Camera dslr = new Camera() {
  @Override
  public String getType() {
    return "Nikon D90 DX";
  }
};
System.out.println(basic.getType());
System.out.println(dslr.getType());

interface Input {
  String getInputType();
};
//anonymous class that implements an interface 
Input in = new Input() {
  @Override 
  public String getInputType() {
    return "Valid Input";
  }
};
System.out.println(in.getInputType());
```
---

# Short Answer Questions: Anonymous Classes (5 minutes)

1. True/False: Anonymous classes must extend a class or implement an interface

2. Can you create a method inside an anonymous class that is *not* an override of the original class? 

3. Can interfaces be instantiated using new? For example, is `Test test = new Test();` going to result in a compiler error if Test is an interface? 

4. When can interfaces be instantiated using new? 

5. Can the anonymous class have a constructor (aside from the constructor in the original class)?

---

# Coding Problem 1: Anonymous Class (5 minutes)

Use an anonymous class to implement the following interface for a language of your choice (I used Spanish in my example). 

```java
interface HelloWorld {
  void greetSomeone(String someone);
};

// create your anonymous class here

spanishGreeting.greetSomeone("Akhila"); //prints Hola Akhila 
```

---

# Coding Problem 2: Anonymous Class (5 minutes)

Use an anonymous class to capture the value of the `tn` variable and implement the `GetName` interface.

```java 
public class State {
  public String name;
  public State(String setName) {
    name = setName;
  }
}

interface GetName {
  String getName();
};

State tn = new State("Tennessee");

System.out.println(example.getName());
tn.name = "Illinois";
System.out.println(example.getName());
```

---

# Two Special Interfaces: Iterable and Iterator  

**iterable**: allows an object to be part of a for-each loop
  - iterable REQUIRES that you implement the `iterator()` method

```java
RandomClass iterable = new RandomClass(8);
for (Object value : iterable) { // we can't do this unless RandomClass implements the iterable interfacce
  System.out.println(value);
}
```

**iterator**: does the grunt work here and figures out what the next item in the collection is and iterates through all the items in the collection 
- iterator REQUIRES that you implement `next()` and `hasNext()`

---

# Coding Problem: Iterable and Iterators (10 minutes)

Modify the class below so that it implements the Iterable and Iterator interfaces correctly. 

```java
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

public class PlaylistIterable implements Iterable, Iterator {
  private List<String> names = new ArrayList<>();
  public PlaylistIterable() {
    names.add("Rams");
    names.add("Posa");
    names.add("Chinni");
  }
}
PlaylistIterable iterable = new PlaylistIterable();
for (Object value : iterable) {
  System.out.println(value);
}
```
---

# That's All Folks!

Do you have other questions? Do you have feedback? Let us know! 

See y'all on Friday. Peace. 

---

# Solution Section

---

# Coding Problem 1: Interfaces (10 minutes)
```java
public interface DungeonMaster {
  boolean canCreateDungeonInstance();
  int increaseHealth();
};

public class Player implements DungeonMaster {
  private String userName;
  private int healthPoints;
  private String state;
  
  public Player(String name) {
    userName = name;
    state = "ALIVE";
    healthPoints = 100;
  }
  public String isAlive() {
    return state;
  }
  
  public boolean canCreateDungeonInstance() {
    return true;
  }
  
  public int increaseHealth() {
    return healthPoints++;
  }
}
```
---
# Coding Problem 2: Interfaces (10 minutes)

```java
public interface DungeonMaster {
  boolean canCreateDungeonInstance();
  int increaseHealth();
};


public class Player implements DungeonMaster, Comparable {
  private String userName;
  private int healthPoints;
  private String state;
  
  public Player(String name) {
    userName = name;
    state = "ALIVE";
    healthPoints = 100;
  }
  public String isAlive() {
    return state;
  }
  
  public boolean canCreateDungeonInstance() {
    return true;
  }
  
  public int increaseHealth() {
    return healthPoints++;
  }
  
  public int compareTo(Object o) {
    assert o instanceof Player;
    Player other = (Player) o;
    if (other.userName == userName) {
      return 0;
    } else {
      if (other.healthPoints > healthPoints) {
        return 1;
      } else if (other.healthPoints < healthPoints) {
        return -1;
      } else {
        return 0;
      }
    }
  }
}
```
---

# Short Answer Questions: Anonymous Classes (5 minutes)

1. True

2. No, anonymous classes are used to override the methods in the class it extends. 

3. No, normally, we cannot instantiate interfaces with new. 

4. Interfaces can be instantiated with new when they are implemented via an anonymous class call.

5. Nope - you need a name to have a constructor :(

---

# Coding Problem 1: Anonymous Class (5 minutes)

```java
interface HelloWorld {
  void greetSomeone(String someone);
};

// create your anonymous class here
HelloWorld spanishGreeting = new HelloWorld() {
  public void greetSomeone(String someone) {
    System.out.println("Hola " + someone);
  }
};

spanishGreeting.greetSomeone("Akhila"); //prints Hola Akhila 
```

---

# Coding Problem 2: Anonymous Class (5 minutes)

```java
public class State {
  public String name;
  public State(String setName) {
    name = setName;
  }
}

interface GetName {
  String getName();
};

State tn = new State("Tennessee");

GetName example = new GetName() {
  @Override
  public String getName() {
    return tn.name;
  }
};


System.out.println(example.getName());
tn.name = "Illinois";
System.out.println(example.getName());

```

---

# Coding Problem: Iterable and Iterators (10 minutes)

```java
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

public class PlaylistIterable implements Iterable, Iterator {
  private List<String> names = new ArrayList<>();
  public PlaylistIterable() {
    names.add("Rams");
    names.add("Posa");
    names.add("Chinni");
  }
  private int i;
  public Iterator iterator() {
    i = 0;
    return this;    
  }
  
  public boolean hasNext() {
    return i < names.size();
  }
  
  public Object next() {
    Object val = names.get(i);
    i++;
    return val;
  }

}
PlaylistIterable iterable = new PlaylistIterable();
for (Object value : iterable) {
  System.out.println(value);
}
```