--- marp: true paginate: true math: mathjax theme: buutti title: 8. Inheritance & Abstract Classes --- # Inheritance & Abstract Classes ## 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
| `class Animal` | `class Dog : Animal` | `class Cat : Animal` | |:--------------:|:--------------------:|:--------------------:| | `Eat()` | `Bark()` | `Meow()` | | `Sleep()` | | |

* Animal can eat * Animal can sleep
* Dog can eat * Dog can sleep * Dog can bark
* Cat can eat * Cat can sleep * Cat can meow
### Inheritance: An example implementation
```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!"); } } ```
```csharp class Program { static void Main(string[] args) { Dog pluto = new Dog(); pluto.Eat(); // Outputs "Eating..." pluto.Bark(); // Outputs "Bark!" } } ```
### 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 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
In this example, an enum is used to keep track of the state of the program. ```csharp enum ProgramState { Login, Menu, Exit } ```
```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; } } } ```
## Extra: Object Oriented Programming * 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 * 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 * 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 * 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 * 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