# Dynamic Method Selection

{% hint style="warning" %}
This is a **very tricky topic**. Make sure you are comfortable with [inheritance](/oop/inheritance.md) and [access control ](/oop/access-control.md)before proceeding!
{% endhint %}

Inheritance is great and all, but it does have some issues. One of the biggest issues lies in overriding: **if two methods have exactly the same name and signature, which one do we call?**

In a standard use case, this is a pretty simple answer: whichever one is in the class we want! Let's look at some basic examples.

```java
public class Dog {
    public void eat() { ... } // A
}

public class Shiba extends Dog {
    @Override
    public void eat() { ... } // C
}
```

{% tabs %}
{% tab title="Question 1" %}
Which method is called when we ru&#x6E;**:**

```java
Dog rarePupper = new Dog();
rarePupper.eat();
```

{% endtab %}

{% tab title="Q1 Answer" %}
It's **A** :dog: Dog doesn't know anything about `Shiba` or any other classes, so we can just look at the Dog.
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Question 2" %}
What about when we call:

```java
Shiba doge = new Shiba();
rarePupper.eat();
```

{% endtab %}

{% tab title="Q2 Answer" %}
This calls **C**! This works intuitively because `Shiba` overrides `Dog` so all `Shibas` will use C instead of A.

![](/files/-M6qbf18G3khmPtgyutR)
{% endtab %}
{% endtabs %}

## Things Get Wonky: Mismatched Types

There's an interesting case that actually works in Java:

```java
Dog confuzzled = new Shiba();
```

What??? Shouldn't this error because `Dog` is incompatible with `Shiba`?&#x20;

It turns out that **subclasses can be assigned to superclasses.** In other words, `Parent p = new Child()` works fine. This is really useful for things like [Interfaces](/oop/inheritance.md#interfaces) and generic [Collections](/abstract-data-types/collections.md) because we might only care about using generic methods, and not the specific implementation that users chose to provide.

However, **it is important to note that it doesn't work the other way.** `Child c = new Parent()` will error because the child might have new methods that don't exist in the parent.

**Let's see how this makes inheritance really tricky:**

```java
/** The following problems are inspired by Spring 2020 Exam Prep 5. */

public class Dog {
    public void playWith(Dog d) { ... } // D
}

public class Shiba extends Dog {
    @Override
    public void playWith(Dog d) { ... } // E
    public void playWith(Shiba s) { ... } // F
}
```

{% tabs %}
{% tab title="Question 3" %}
Which method(s) run when we call:

```java
Dog rarePupper = new Shiba();
rarePupper.playWith(rarePupper); // aww rarePupper is lonely :(
```

{% endtab %}

{% tab title="Q3 Answer" %}
**E** is called! What happens is that the **dynamic type** is chosen to **select the method from,** but the **static type** is used to **select the parameters.** `rarePupper`'s dynamic type is `Shiba` but its static type is `Dog` so `Shiba.playWith(Dog)` is chosen as the method.

![rarePupper in action](/files/-M6rCRBLiGUyIrzdjjJA)
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Question 4" %}
Which is called when we ru&#x6E;**:**

```java
Dog rarePupper = new Shiba();
Shiba doge = new Shiba();
rarePupper.playWith(doge); // rarePupper is happy :) borks all around
```

{% endtab %}

{% tab title="Q4 Answer" %}
**E** is called again! Bet ya didn't see that coming 😎

**Why is it not F? I thought doge and rarePupper were both** `Shiba`**?**\
When the compiler chooses a method, it **always** starts at the **static method.** Then, it keeps going down the inheritance tree until it hits the **dynamic method.** Since F has a **different signature** than D, it isn't an **overriding method** and thus the compiler won't see it. But E is (since it has the same signature as D), so that is why it is chosen instead.

![bork bork bork :DDD](/files/-M6rCia6Iuj5Cd2lyidy)
{% endtab %}
{% endtabs %}

## Adding more insanity: Static vs. Dynamic

By now, you should have a pretty good understanding of the **method selection** part of DMS. But why is it **dynamic?**

You may have noticed that there are **two** type specifiers in an instantiation. For example, `Dog s = new Shiba()` has type `Dog` on the left and `Shiba` on the right.

Here, `Dog` is the **static type** of `s`: it's what the compiler believes the type should be when the program is compiled. Since the program hasn't run yet, Java doesn't know what exactly it is- it just knows it has to be some type of `Dog`.

Conversely, `Shiba` is the **dynamic type:** it gets assigned during runtime.

### The type rules

Just remember: **like chooses like.** If a method is **static**, then choose the method from the **static type.** Likewise, if a method is **not static,** choose the corresponding method from the **dynamic type.**&#x20;

Let's try some examples!

```java
public class Dog {
    public static String getType() {
        return "cute doggo";
 
    @Override // Remember, all objects extend Object class!   
    public String toString() {
        return getType();
    }
}

public class Shiba extends Dog {
    public static String getType() {
        return "shiba inu";
    }
}
```

{% tabs %}
{% tab title="Question 5" %}
What prints out when we run:

```java
Dog d = new Shiba();
System.out.println(d.getType());
```

{% endtab %}

{% tab title="Q5 Answer" %}
`cute doggo` gets printed because `getType()` is a static method! Therefore, Java looks at the **static type** of `d`, which is `Dog`. \
(If `getType()` weren't static, then `shiba inu` would have been printed as usual.)
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Question 6" %}
What prints out when we run:

```java
Shiba s = new Shiba();
System.out.println(s);
```

{% endtab %}

{% tab title="Q6 Answer" %}
`cute doggo` also gets printed!! This is because static methods **cannot be overridden.** When `toString()` is called in `Dog`, it doesn't choose `Shiba`'s `getType()` because `getType()` is static and the static type is `Dog`.
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Question 7" %}
What prints out when we run:

```java
Dog d = new Shiba();
System.out.println(((Shiba)d).getType());
```

{% endtab %}

{% tab title="Q7 Answer" %}
This time, `shiba inu` gets printed. This is because casting temporarily changes the **static type:** since the static type of `d` is  `Shiba` in line 2, it chooses the `getType()` from `Shiba`.
{% endtab %}
{% endtabs %}

## That's all, folks!

If you want some **even harder** problems, [check this out](https://inst.eecs.berkeley.edu/~cs61b/sp20/materials/disc/examprep5.pdf) and also [this](https://inst.eecs.berkeley.edu/~cs61b/sp20/materials/disc/examprep6.pdf).

![bai bai!](/files/-M6rDt9GCK0o4AeXRqDt)


---

# 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://cs61b.bencuan.me/oop/dynamic-method-selection.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.
