finish lectures 8-10

- fix code snippets
- update readme
main
borb 2 weeks ago
parent 76b49a6af8
commit 24ec8f9349

@ -68,10 +68,10 @@
},
"exercise slide" : {
"scope": "markdown",
"prefix": "\"exercise invert\"",
"prefix": "exercise",
"body": [
"## Exercise $0.",
"<!--_class: exercise -->",
"<!--_class: \"exercise invert\" -->",
],
"description": "Exercise slide colors"
},

File diff suppressed because one or more lines are too long

@ -1,233 +1,198 @@
# Static Members, Methods and Classes
![](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_0.png)
---
marp: true
paginate: true
math: mathjax
theme: buutti
title: 10. Static Members, Methods and Classes
---
# Static Members
# Static Members, Methods and Classes
So far, we have used __non-static__ fields in our classes
<!-- headingDivider: 5 -->
<!-- class: invert -->
This means, that each instance of the class holds its own version of the field, and changing the value of it only affects that instance:
## Static Members
class MyAwesomeClass
### Non-static members
* So far, we have used *__non-static__* fields in our classes
* Meaning that each instance of the class holds its own version of the field, and changing the value of it only affects that instance:
```csharp
class MyAwesomeClass
{
public int MyProperty { get; set; }
}
class Program
{
static void Main(string[] args)
{
MyAwesomeClass instance1 = new MyAwesomeClass();
MyAwesomeClass instance2 = new MyAwesomeClass();
instance1.MyProperty = 100;
instance2.MyProperty = 200; // instance1.MyProperty is still 100
}
}
```
# Static Members (continued)
Likewise, non-static class methods _have to _ be called through an instance:
---
* Likewise, non-static class methods **_have to_** be called through an instance:
```csharp
class MyAwesomeClass
{
public void PrintText(string text) { Console.WriteLine(text); }
public void PrintText(string text)
{
Console.WriteLine(text);
}
}
class Program
{
static void Main(string[] args)
{
MyAwesomeClass instance = new MyAwesomeClass();
instance.PrintText("Hello World"); // Outputs "Hello World"
MyAwesomeClass.PrintText("Hello World"); // Results in an error
}
}
```
<div class='centered'>
![](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_1.png)
![w:500px](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_1.png)
__Static fields are shared between all instances of a class__
</div>
Let's declare "MyProperty" property with the __static __ keyword. Now it can be referenced through the class type name, but not through the instance, as shown below:
### Static members
* Let's declare a property `MyProperty` with the `static` keyword
* It can be referenced *through the class*, but ***not*** through the instance:
```csharp
class MyAwesomeClass
{
public static int MyProperty { get; set; } = 100;
}
class Program
{
static void Main(string[] args)
{
MyAwesomeClass instance = new MyAwesomeClass();
Console.WriteLine(MyAwesomeClass.MyProperty); // Outputs "100"
Console.WriteLine(instance.MyProperty); // Results in an error
}
}
```
![](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_2.png)
<div class='centered'>
# Static Members - Example
![w:600px](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_2.png)
In this example, a static field is used for keeping count on how many times the class has been instantiated:
</div>
class Person
{
### Static members: An example
* In this example, a static field is used for keeping count on how many times the class has been instantiated:
```csharp
class Person
{
public static int totalPersons = 0;
private string name;
public Person(string personName) // Person Constructor
{
name = personName;
++totalPersons;
}
public void PrintInfo()
{
Console.WriteLine("This person is called " + name + ".");
Console.WriteLine("There are " + totalPersons + " persons total.");
}
}
```
# Static Members - Example (continued)
---
Now let's instantiate a couple of persons and print their info:
class Program
* Now let's instantiate a couple of persons and print their info:
{
<div class='columns21' markdown='1'>
<div markdown='1'>
```csharp
class Program
{
static void Main(string[] args)
{
Person steve = new Person("Steve");
Person wendy = new Person("Wendy");
steve.PrintInfo();
wendy.PrintInfo();
}
}
```
![](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_3.png)
</div>
<div markdown='1'>
# Static Methods
![w:400px](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_3.png)
Methods can also be static
</div>
</div>
What happens when you try to call a non-static method from a static method?
## Static methods
* Methods can also be static
* What happens when you try to call a non-static method from a static method?
```csharp
class Program
{
void PrintHelloName(string name)
{
Console.WriteLine("Hello, " + name);
}
static void Main(string[] args)
{
PrintHelloName(); // Will throw an error
}
}
```
![](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_4.png)
---
This is why until this point all example methods have been inside of the main function
# Static Classes
<div class='centered'>
* Classes can also be made static
* Static classes cannot be instantiated
* All members of a static class also have to be static
* static class Styling
* {
* public static string fontFamily = "Verdana";
* public static float fontSize = 12.5f;
* }
* class Program
* {
* static void Main(string[] args)
* {
* Console.WriteLine
* ("Using font " + Styling.fontFamily + " " + Styling.fontSize + "px");
* // Outputs "Using font Verdana 12.5px"
* Styling = new Styling(); // Results in an error
* }
* }
![w:800px](imgs/10%20Static%20Members%2C%20Methods%20and%20Classes_4.png)
# Exercise 1
</div>
Create a class Message which has two __static __ properties int TotalMessages and string LastMessage, and a __non-static __ property string MessageText.
## Static classes
Add a constructor which takes a string message as a parameter, increases TotalMessages by one and sets the value of LastMessage to message which is the parameter
* Whole classes can also be static
* Static classes cannot be instantiated, and all its members have to be static as well
```csharp
static class Styling
{
public static string fontFamily = "Verdana";
public static float fontSize = 12.5f;
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine
("Using font " + Styling.fontFamily + " " + Styling.fontSize + "px");
// Outputs "Using font Verdana 12.5px"
Styling = new Styling(); // Results in an error
}
}
```
Create a main loop which keeps asking the user for a new message. A new Message instance is then created with the user input message as an argument:
## Exercise 1
<!--_class: "exercise invert" -->
* Create a class `Message` that has two `static` properties `int TotalMessages` and `string LastMessage`, and a *__non-static__* property `string MessageText`.
* Add a constructor that takes a `string message` as a parameter, increases `TotalMessages` by one and sets the value of `LastMessage` to `message`.
* Create a main loop that keeps asking the user for a new message. A new `Message` instance is then created with the user input message as an argument:
```csharp
Message newMessage = new Message(message);
newMessage is then added to a list of messages, allMessages
Finally the static values Message.TotalMessages and Message.LastMessage are printed
```
* `newMessage` is then added to a list `allMessages`.
* Finally, the static values `Message.TotalMessages` and `Message.LastMessage` are printed.

File diff suppressed because one or more lines are too long

@ -1,302 +1,307 @@
# Inheritance & Abstract Classes
![](imgs/8%20Inheritance%20%26%20Abstract%20Classes_0.png)
---
marp: true
paginate: true
math: mathjax
theme: buutti
title: 8. Inheritance & Abstract Classes
---
# Overview
Inheritance
Abstract Classes
# Inheritance & Abstract Classes
Enums
<!-- headingDivider: 5 -->
<!-- class: invert -->
# Inheritance
## Overview
Classes can be made to inherit functionality of some other class
* Inheritance
* Abstract classes
* Enums
* OOP
If class B inherits class A, all of the (public) functionality in class A is also available in class B
## Inheritance
A is called the __base class__ (or parent class) and B is called the __derived class __ (or child class)
* 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
Use the " __:"__ symbol to make a class inherit from another
### An inheritance example
Try to understand the following example:
<center>
| class Animal |
| :-: |
| -Eat()-Sleep() |
| `class Animal` | `class Dog : Animal` | `class Cat : Animal` |
|:--------------:|:--------------------:|:--------------------:|
| `Eat()` | `Bark()` | `Meow()` |
| `Sleep()` | | |
| class Dog : Animal |
| :-: |
| -Bark() |
</center>
| class Cat : Animal |
| :-: |
| -Meow() |
<br>
Animal can eat
<div class='columns111' markdown='1'>
<div markdown='1'>
Animal can sleep
* Animal can eat
* Animal can sleep
Dog can eat
</div>
<div markdown='1'>
Dog can sleep
* Dog can eat
* Dog can sleep
* Dog can bark
Dog can bark
</div>
<div markdown='1'>
Cat can eat
* Cat can eat
* Cat can sleep
* Cat can meow
Cat can sleep
</div>
</div>
Cat can meow
### Inheritance: An example implementation
# Inheritance - Example
<div class='columns' markdown='1'>
<div markdown='1'>
```csharp
class Animal
{
public void Eat() { Console.WriteLine("Eating..."); }
public void Sleep() { Console.WriteLine("Sleeping..."); }
public void Eat()
{ Console.WriteLine("Eating..."); }
public void Sleep()
{ Console.WriteLine("Sleeping..."); }
}
class Cat : Animal
{
public void Meow() { Console.WriteLine("Meow!"); }
public void Meow()
{ Console.WriteLine("Meow!"); }
}
class Dog : Animal
{
public void Bark() { Console.WriteLine("Bark!"); }
public void Bark()
{ Console.WriteLine("Bark!"); }
}
```
class Program
</div>
<div markdown='1'>
```csharp
class Program
{
static void Main(string[] args)
{
Dog pluto = new Dog();
pluto.Eat(); // Outputs "Eating..."
pluto.Bark(); // Outputs "Bark!"
}
}
```
# Inheritance
</div>
</div>
All the objects deriving from the same base class can be referenced with the base class name:
### 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:
```
* 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 __casted __ into the child class type:
```
* 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__
* 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:
* 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:
## 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
}
}
```
class Pig : Animal
---
* 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:
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 }}
```
---
This is called abstraction, which is one of the key concepts of OOP
# Exercise 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
Give Dog, Cat and Pig some fields and/or methods specific to that animal
Create a few instances of Dog, Cat and Pig classes, and add them to a new list of Animals, named "allAnimals"
Loop through allAnimals with the foreach statement, and call the Greet() method of each animal
* 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
}
}
```
# Enum
## Exercise 1. Animal farm
<!--_class: "exercise invert" -->
__Enum __ (short for enumeration) is a data type for holding a set of constant (immutable) names
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 can be useful when you have a number of items or states that are predefined, for example, weekdays
## Enums
Create the enum type with the enum keyword:
* [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`
enum Weekday{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}
### Creating enums
New instances of the enum can only be assigned one of the values within:
* 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;
```
Weekday currentDay = Weekday.Monday;
### Enums: An example
# Enum - Example
<div class='columns12' markdown='1'>
<div markdown='1'>
In this example, enum is used to keep track of the state of the program:
In this example, an enum is used to keep track of the state of the program.
```csharp
enum ProgramState
{
Login,
Menu,
Exit
}
```
static void Main(string[] args)
</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>
# Going Further: Object Oriented Programming
## 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
* 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, and
* Abstraction
* Polymorphism
# OOP: Encapsulation
Earlier we created classes which hold properties and methods, which 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 made available _only when it is needed _ by instantiating an object of the class
# OOP: Inheritance
As shown in the lecture slides, inheritance allows you to write some functionality once, and then create separate classes which all share that same functionality
This removes the need to write the same code inside every class
# OOP: Abstraction
### Encapsulation
<!-- _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
* 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
Instead, reveal only the parts that the user (you, a workmate, etc) actually need, with abstraction
### Inheritance
<!-- _class: "extra invert" -->
Parable: The user of a microwave doesn't have to know about the complicated circuitry inside of the microwave. Only the buttons are revealed
* 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
# OOP: Polymorphism
### Abstraction
<!-- _class: "extra invert" -->
This concept becomes more clear after we have covered interfaces
* 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 refers to multiple classes having the same method but with different functionality
### Polymorphism
<!-- _class: "extra invert" -->
This reduces the need for massive if-else and switch..case statements
* 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

File diff suppressed because one or more lines are too long

@ -1,270 +1,248 @@
# Interfaces
![](imgs/9%20Interfaces_0.png)
---
marp: true
paginate: true
math: mathjax
theme: buutti
title: 9. Interfaces
---
# Interfaces
# Overview
<!-- headingDivider: 5 -->
<!-- class: invert -->
Interfaces
## Overview
Interfaces or Inheritance?
* Interfaces
* Interfaces or Inheritance?
# Interfaces
## Interfaces
* In addition to abstract classes, __interfaces __ are a way to achieve abstraction to your program
* Interfaces are classes that have __no internal functionality__
* Interfaces describe the methods and properties that a class has to have when implementing the interface
* Think of it as a _contract_ : by __implementing __ an interface, the class _has to_ _use _ all the methods and properties that are defined in the interface
* As with abstract classes, interfaces cannot be instantiated directly
* It wouldn't make any sense as interfaces have no implementation
* In addition to abstract classes, *__interfaces__* are a way to achieve abstraction to your program
* Interfaces are classes that have *__no internal functionality__*
* Interfaces describe the methods and properties that a class has to have when ***implementing*** the interface
* Think of it as a ***contract***: by implementing an interface, the class **_has to use_** all the methods and properties defined in the interface
* As with [abstract classes](8-inheritance-and-abstract-classes.md#abstract-classes), interfaces cannot be instantiated directly
* (It wouldn't make any sense as interfaces have no implementation)
* Interfaces are way more commonly used than abstract classes
# Creating an Interface
### Creating an interface
* Define an interface using the interface keyword instead of class:
* interface IUser
* {
* int Id { get; set; }
* string Name { get; set; }
* void GetUserStatistics();
* }
* Interface names should begin with the capital I letter to more easily identify them as interfaces and not classes
* Notice that interfaces can contain both properties and methods but not fields
```csharp
interface IUser
{
int Id { get; set; }
string Name { get; set; }
void GetUserStatistics();
}
```
* [Interface names should begin](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces) with the capital letter `I` to more easily identify them as interfaces and not classes
* Notice that interfaces can contain both properties and methods ***but not fields***
* Methods are declared without the method body (no implementation)
* The methods are implemented on the classes that uses the interface
# Implementing an Interface
Implement an interface just like you would inherit a class:
### Implementing an interface
* Implement an interface just like you would inherit a class:
```csharp
class User : IUser
{
}
```
* The compiler will now throw a bunch of errors saying that the User class does not implement the properties and methods defined in the interface
* Let's fix that by defining those next
The compiler will now throw a bunch of errors saying that the User class does not implement the properties and methods defined in the interface
Let's fix that by defining those now
# Implementing an Interface (continued)
---
```csharp
class User : IUser
{
public int Id { get; set; }
public string Name { get; set; }
public void GetUserStatistics()
{
// Some code here
}
}
```
* The interface is now fully implemented and the compiler is happy
* The interface does not dictate **_how_** the methods are implemented, those just need to be implemented
* ***Note:*** To quickly implement the interface, click the IUser interface name and click _💡 > Implement interface_.
The interface is now fully implemented and the compiler is happy
The interface do not dictate _how_ the methods are implemented, those just need to be implemented.
To quickly implement the interface, click the IUser interface name and click the light bulb -> implement interface.
# Implementing Multiple Interfaces
### Implementing multiple interfaces
* Unlike with inheritance, classes can implement multiple interfaces
* In contrast, classes can only inherit from one base class
* This is done by separating the interfaces with a comma:
* class Rock : IPickable, IThrowable, ICrushable
* {
* // Code that implements IPickable, IThrowable and ICrushable
* }
# Why Use Interfaces?
Interfaces allow common functionality among classes that are otherwise unrelated to each other
In those cases, inheriting from some shared base class wouldn't make sense
```csharp
class Rock : IPickable, IThrowable, ICrushable
{
// Code that implements IPickable, IThrowable and ICrushable
}
```
Consider the following example:
### Why use interfaces?
* Interfaces allow common functionality among classes that are otherwise unrelated to each other
* In those cases, inheriting from some shared base class wouldn't make sense
* Consider the following example:
```csharp
public void DeleteData(IDeletable data)
{
data.Delete();
}
```
* The above method accepts **_any_** type of object that implements `IDeletable`, regardless of other functionality
The above method accepts _any _ type of object that implements IDeletable, regardless of other functionality
## Interface or Inheritance?
# Interface or Inheritance?
### Example 1
| class Dog |
| :-: |
| -Eat()-Sleep()-WagTail() |
<center>
| class Human |
| :-: |
| -Eat()-Sleep()-Contemplate() |
| `class Dog` | `class Human` | `class Bear` |
|:------------|:----------------|:--------------|
| `Eat()` | `Eat()` | `Eat()` |
| `Sleep()` | `Sleep()` | `Sleep()` |
| `WagTail()` | `Contemplate()` | `Hibernate()` |
| class Bear |
| :-: |
| -Eat()-Sleep()-Hibernate() |
</center>
All classes could inherit from a base class Animal, which has methods Eat() and Sleep()
* All classes could inherit from a base class `Animal`, which has methods `Eat()` and `Sleep()`
* The question is, should the base class be abstract?
* Depends on your program: do you ever need an object that can ***only*** `Eat()` and `Sleep()`?
Should the base class be abstract? Depends on your program: do you ever need an object that can only Eat() and Sleep()?
### Example 2
| class Tree |
| :-: |
| -Grow()-Photosynthesize() |
<center>
| class Human |
| :-: |
| -Grow()-Move() |
| `class Tree` | `class Human` | `class Car` |
|:--------------------|:--------------|:------------|
| `Grow()` | `Grow()` | `Explode()` |
| `Photosynthesize()` | `Move()` | `Move()` |
| class Car |
| :-: |
| -Move()-Explode() |
</center>
It wouldn't make sense to use inheritance here, since there is no functionality that is shared between all classes
* It wouldn't make sense to use inheritance here, since there is no functionality that is shared between ***all*** classes
* Instead you could make two interfaces: `IGrowable` and `IMovable`
Instead you could make two interfaces: IGrowable and IMovable
## Interfaces: An example
# Interfaces - Example
* Let's make a program that has two lists: one for all objects that can move (`IMovable`) and one for all objects that can be carried (`ICarryable`)
* Finally, every movable object is moved and carryable object is carried
Let's make a program that has two lists: one for all objects that can move (IMovable) and one for all objects that can be carried (ICarryable)
---
Finally every movable object is moved and carryable object is carried
<div class='columns12' markdown='1'>
<div markdown='1'>
```csharp
interface IMovable
{
void Move();
}
interface ICarryable
{
void Carry();
}
```
class Elephant : IMovable
</div>
<div markdown='1'>
```csharp
class Elephant : IMovable
{
public void Move()
{
Console.WriteLine("The elephant is moving'");
}
}
class Cat : IMovable, ICarryable
{
public void Move()
{
Console.WriteLine("The cat is moving'");
}
public void Carry()
{
Console.WriteLine("You are carrying the cat");
}
}
class Rock : ICarryable
{
public void Carry()
{
Console.WriteLine("You are carrying the rock");
}
}
```
class Program
</div>
</div>
{
---
static void Main(string[] args)
<div class='columns21' markdown='1'>
<div markdown='1'>
```csharp
class Program
{
static void Main(string[] args)
{
Elephant elephant = new Elephant();
Cat cat = new Cat();
Rock rock = new Rock();
List<IMovable> movables = new List<IMovable>{ elephant, cat };
List<ICarryable> carryables = new List<ICarryable>{ cat, rock };
List<IMovable> movables =
new List<IMovable>{ elephant, cat };
List<ICarryable> carryables =
new List<ICarryable>{ cat, rock };
foreach (IMovable movable in movables)
movable.Move();
foreach (ICarryable carryable in carryables)
carryable.Carry();
}
}
```
![](imgs/9%20Interfaces_1.png)
# Exercise 1: A Web of Relations
</div>
<div markdown='1'>
Create a console application that has an interface IInfo, and two classes Product and Category, which both implement IInfo.
![](imgs/9%20Interfaces_1.png)
Inside IInfo, declare a property InfoText and a method PrintInfo
</div>
</div>
Implement the property and method in Product and Category
Initialize a couple of products and categories, with info texts of your choice
Create a list of type IInfo, and add the products and categories to it
## Exercise 1: A web of relations
<!--_class: "exercise invert" -->
Create a main loop, where each time the user presses enter, all the info texts inside the list are printed
Create a console application that has an interface `IInfo` and two classes `Product` and `Category` that both implement `IInfo`.
# Exercise 2: The IComparable Interface
1) Inside `IInfo`, declare a property `InfoText` and a method `PrintInfo`
2) Implement both the property and method in `Product` and `Category`
3) Initialize a couple of products and categories, with info texts of your choice
4) Create a list of type `IInfo`, and add the products and categories to it
5) Create a main loop, where each time the user presses enter, all the info texts inside the list are printed
Create a program that sorts a list of shapes by area, using the [IComparable](https://docs.microsoft.com/en-us/dotnet/api/system.collections.icomparer?view=netcore-3.1) interface, which is used by the List.Sort() method to know whether the elements should come before or after each other in the list.
## Exercise 2: The `IComparable` Interface
<!--_class: "exercise invert" -->
Start by creating 4 classes: __Shape__ , __Square__ , __Triangle__ and __Circle__ . Square, Triangle and Circle inherit from Shape. Shape implements the __IComparable\<Shape>__ __ __ interface.
Create a program that sorts a list of shapes by area, using the [IComparable](https://docs.microsoft.com/en-us/dotnet/api/system.collections.icomparer?view=netcore-3.1) interface which is used by the `List.Sort()` method to know whether the elements should come before or after each other in the list.
Shape has a public property double Area. Square, Triangle and Circle have to have constructors to calculate the area: Square and Triangle with length and height, and Circle with radius.
1) Start by creating 4 classes: `Shape`, `Square`, `Triangle`, and `Circle`. `Square`, `Triangle` and `Circle` inherit from `Shape`, which implements the `IComparable<Shape>` interface.
2) Shape has a public property `double Area`. `Square`, `Triangle` and `Circle` have to have constructors to calculate the area: `Square` and `Triangle` with `length` and `height`, and `Circle` with `radius`.
The CompareTo(Shape? other) method should return 1 if the area is greater than what is being compared with (Shape other), 0 if the areas are equal, and -1 if the area is smaller.
---
<!--_class: "exercise invert" -->
Try out your solution by creating a couple of squares, triangles and circles in a list of shapes, and sorting the list with the .Sort() method. Print the areas in the sorted array with a foreach loop. They should be printed in an increasing order.
3) `The CompareTo(Shape? other)` method should return `1` if the area is greater than what is being compared with (`Shape other`), `0` if the areas are equal, and `-1` if the area is smaller.
4) Try out your solution by creating a couple of squares, triangles and circles in a list of shapes, and sorting the list with the `.Sort()` method.
5) Print the areas in the sorted array with a `foreach` loop. They should be printed in an increasing order.

@ -4,6 +4,9 @@ Material completion denoted with 🌑🌘🌗🌖🌕 .
| # | Lecture | Materials | Exercises |
|---:|------------------------------------------------------------------------|----------:|----------:|
| 8 | [Inheritance and Abstract Classes](8-inheritance-and-abstract-classes.md) | 🌕 | 🌕 |
| 9 | [Interfaces](9-interfaces.md) | 🌕 | 🌕 |
| 10 | [Static Members, Methods, and Classes](10-static-members-methods-and-classes.md) | 🌕 | 🌕 |
| 11 | [Delegates and Events](11-delegates-and-events.md) | 🌕 | 🌗 |
| 12 | [Files and Streams](12-files-and-streams.md) | 🌕 | 🌕 |
| 13 | [Generics, IEnumberable and LINQ](13-generics-ienumerable-and-linq.md) | 🌕 | 🌕 |

Loading…
Cancel
Save