---
marp: true
paginate: true
math: mathjax
theme: buutti
title: 8. Inheritance & Abstract Classes
---

# Inheritance & Abstract Classes

<!-- headingDivider: 5 -->
<!-- class: invert -->

## Overview

* Inheritance
* Abstract classes
* Enums
* OOP

## Inheritance

* Classes can be made to inherit functionality of some other class
* If class B inherits class A, all of the (public) functionality in class A is also available in class B
* A is called the *__base class__* (or parent class) and B is called the *__derived class__* (or child class)
* Use the `:` symbol to make a class inherit from another

### An inheritance example

<center>

| `class Animal` | `class Dog : Animal` | `class Cat : Animal` |
|:--------------:|:--------------------:|:--------------------:|
| `Eat()`        | `Bark()`             | `Meow()`             |
| `Sleep()`      |                      |                      |

</center>

<br>

<div class='columns111' markdown='1'>
<div markdown='1'>

* Animal can eat
* Animal can sleep

</div>
<div markdown='1'>

* Dog can eat
* Dog can sleep
* Dog can bark

</div>
<div markdown='1'>

* Cat can eat
* Cat can sleep
* Cat can meow

</div>
</div>

### Inheritance: An example implementation

<div class='columns' markdown='1'>
<div markdown='1'>

```csharp
class Animal
{
  public void Eat()
  { Console.WriteLine("Eating..."); }
  public void Sleep()
  { Console.WriteLine("Sleeping..."); }
}
class Cat : Animal
{
  public void Meow()
  { Console.WriteLine("Meow!"); }
}
class Dog : Animal
{
  public void Bark()
  { Console.WriteLine("Bark!"); }
}
```

</div>
<div markdown='1'>

```csharp
class Program
{
  static void Main(string[] args)
  {
    Dog pluto = new Dog();
    pluto.Eat();    // Outputs "Eating..."
    pluto.Bark();   // Outputs "Bark!"
  }
}
```

</div>
</div>

### Inheritance continued

* All the objects deriving from the same base class can be referenced with the base class name:
  ```csharp
  Animal whiskersAnimal = new Cat();
  Animal plutoAnimal = new Dog();
  ```
* However, only the methods of the base class are available for objects of the base class type:
  ```csharp
  plutoAnimal.Eat();    // Outputs "Eating..."
  plutoAnimal.Bark();   // Error
  ```
* An object of base class type can be *__cast__* into the child class type:
  ```csharp
  Dog pluto = (Dog)plutoAnimal;
  pluto.Bark();   // Outputs "Bark!"
  ```

## Abstract Classes

* In some cases you want the base class to be made [abstract](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract)
* Objects of an abstract class ***cannot*** be instantiated
  * For example, where would you need a generic `Animal` by itself?
* Make a class abstract with the `abstract` keyword:
  ```csharp
  abstract class Animal
  {
    public void Eat() { Console.WriteLine("Eating..."); }
    public void Sleep() { Console.WriteLine("Sleeping..."); }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Animal animal = new Animal();      // This will throw an error
    }
  }
  ```

---

* Instead, the methods are accessible through a derived class:
  ```csharp
  abstract class Animal
  {
    public void Eat() { Console.WriteLine("Eating..."); }
    public void Sleep() { Console.WriteLine("Sleeping..."); }
  }
  class Pig : Animal
  {
    public void Squeal() { Console.WriteLine("Squeee!"); }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Pig pig = new Pig();
      pig.Sleep();    // Outputs "Sleeping..."
      pig.Squeal();   // Outputs "Squeee!"
    }
  }
  ```

---

* If you know you only need the functionality of the abstract class, instantiate the new class as a type of abstract class:
  ```csharp
  abstract class Animal
  {
    public void Eat() { Console.WriteLine("Eating..."); }
    public void Sleep() { Console.WriteLine("Sleeping..."); }
  }
  class Pig : Animal
  {
    public void Squeal() { Console.WriteLine("Squeee!"); }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Animal pig = new Pig();
      pig.Sleep();    // Outputs "Sleeping..."
      pig.Squeal();   // This will throw an error
    }
  }
  ```

## Exercise 1. Animal farm
<!--_class: "exercise invert" -->

1) Create the classes `Animal`, `Dog`, `Cat` and `Pig`. `Animal` is the same as before (strings `name` and `sound` and the `Greet()` method). `Dog`, `Cat` and `Pig` inherit `Animal`
2) Give `Dog`, `Cat` and `Pig` some fields and/or methods specific to that animal
3) Create a few instances of `Dog`, `Cat` and `Pig`, and add them to a list `allAnimals`
4) Loop through `allAnimals` with the `foreach` statement, and call the `Greet()` method of each animal

## Enums

* [Enum](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum) (short for enumeration) is a data type for holding a set of constant (immutable) names
* Enums can be useful when you have a given number of ***states*** that are predefined
  * For example, weekdays
  * Another example is an extension of boolean with three states `True`, `False` and `Maybe`

### Creating enums

* Create an `enum` type with the enum keyword:
  ```csharp
  enum Season
  {
    Spring,
    Summer,
    Autumn,
    Winter
  }
  ```
* Then, create a new variable with the type `Season` and assign one of the enum type's values to it:
  ```csharp
  Season currentSeason = Season.Spring;
  ```

### Enums: An example

<div class='columns12' markdown='1'>
<div markdown='1'>

In this example, an enum is used to keep track of the state of the program.

```csharp
enum ProgramState
{
  Login,
  Menu,
  Exit
}
```

</div>
<div markdown='1'>

```csharp
static void Main(string[] args)
{
  ProgramState currentState = ProgramState.Login;
  while (true)
  {
    switch (currentState)
    {
      case ProgramState.Login:
        // Switch current state to Menu after logging in
        break;
      case ProgramState.Menu:
        // Switch current state to Exit if user exits
        break;
      case ProgramState.Exit:
        // Exit the program with an exit message
        break;
    }
  }
}
```

</div>
</div>

## Extra: Object Oriented Programming
<!-- _class: "extra invert" -->

* The instances that are created with the `new` keyword are ***objects***.
* This is literally what ***object orientation*** refers to: packing functionality into these reusable variables that are holding some data and can be passed around
* The key concepts of OOP are:
  * Encapsulation
  * Inheritance
  * Abstraction
  * Polymorphism

### Encapsulation
<!-- _class: "extra invert" -->

* Earlier we created classes that hold properties and methods that are only accessible elsewhere ***after*** instantiating an object of the class
* All the functionality is encapsulated inside of the class instead of lying around in the codebase
* All the functionality is made available **_only when it is needed_** by instantiating an object of the class

### Inheritance
<!-- _class: "extra invert" -->

* As shown earlier, inheritance allows you to write some functionality once, and then create separate classes which all share that same functionality
* This removes the need to rewrite the same code inside every class

### Abstraction
<!-- _class: "extra invert" -->

* When your class contains a lot of complicated functionality, it doesn't always make sense to reveal everything when the class is used
* Instead, reveal only the parts that the user (you, a workmate, etc) actually need, with abstraction
* Example: The user of a microwave doesn't have to know about the complicated circuitry inside of the microwave. Only the buttons are revealed

### Polymorphism
<!-- _class: "extra invert" -->

* This concept becomes more clear after we have covered interfaces in the next lecture
* Polymorphism refers to multiple classes having the same method but with different functionality
* This reduces the need for massive if-else and switch..case statements

