---
marp: true
paginate: true
math: mathjax
theme: buutti
title: 7. Classes And Objects
---

# Classes And Objects

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

## Overview

* Namespaces
* Classes
* Object Variables
* Access Specifiers
* Class Members
* Constructors
* Value & Reference Types

## Namespaces

* Using namespaces helps you to organize the scope of your project, so that...
  * Variable names do not clash
  * Related variables are well-contained in their own namespaces
    * $\Rightarrow$ easy to import what you need
* By default, when creating a new project and adding classes in Visual Studio, everything is contained within a namespace named after your project name

---

* If you need a class, interface, etc to be accessible from anywhere, create it within that namespace and set it as `public`

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

```csharp
// Note that namespaces can have
// subdirectories, as Models here

namespace MyAwesomeApp.Models
{
  public class Student
  {

  }
}
```

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

```csharp
// This is how you would use the
// Student class in other code

using MyAwesomeApp.Models
```

</div>
</div>

* Wait, what's a class, though?



## Classes

* [Classes](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes) in C# are blueprints for specific kinds of collections of data & functionality
* ***Instance*** of a class is an implementation of that class, also referred to as an ***object***
* As C# is an object-oriented language, almost everything has to happen in a class
* Thus, we have already used a class named  `Program` when creating a new console application:
  ```csharp
  class Program
  {
    static void Main(string[] args)
    {

    }
  }
  ```

### Why classes?

* Classes are a core feature of the ***object-oriented programming*** paradigm popularized by Java in the 90s
  * (See [Lecture 8](8-inheritance-and-abstract-classes#extra-object-oriented-programming))
* Classes provide *__encapsulation__*: Connected concepts and functionalities are neatly contained within a class
* This will ***ideally*** result in shorter files, less repetitive code  and ***hopefully*** overall better readability
* No paradigm is idiot-proof, though...
* Shorter files can also mean that it's hard to find the actual functionality from hundreds of short files full of intermediate classes and class factories

### Creating a class

* You can create a new class by writing
  ```csharp
  class Student
  {

  }
  ```
* Create variables inside a class just like before inside the `Program` class:
  ```csharp
  class Student
  {
    int id;
    string name;
  }
  ```
* These variables declared directly inside classes are called *__fields__*.

### Instancing a class

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

* New instances of a class can be created with the `new` keyword
* All instances of a class have exactly the same fields and methods, but they can have different values
* In the following example a few ***objects*** of class `Student` are created
* However, these objects have no functionality yet

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

```csharp

namespace MyAwesomeApp
{
  class Student
  {

  }
  class Program
  {
    static void Main(string[] args)
    {
      Student student1 = new Student();
      Student student2 = new Student();
      Student student3 = new Student();
    }
  }
}
```

</div>
</div>

### Object variables

* Variables inside of an object can be accessed with the `.` operator
* However, the following syntax results in an error:

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

```csharp
class Student
{
  int id;
}
```

Error:
![](imgs/7%20Classes%20and%20Objects_2.png)


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

Program class:

```csharp
class Program
{
  static void Main(string[] args)
  {
    Student student = new Student();
    student.id = 12345678;
  }
}
```

</div>
</div>

---

Let's fix the previous example by changing the *__access specifier__* of the variable `id` to `public`:


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

```csharp
class Student
{
  public int id;
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    Student student = new Student();
    student.id = 12345678;
  }
}
```

</div>
</div>

* The value of the variable `id` of the object `student` is now `12345678`

## Access modifiers

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

* [Access modifiers](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers) can be used to get additional level of protection inside classes
* `private`: accessible only inside the containing class
  * This is the default, but we can make it more explicit by writing it out
* `public`: accessible everywhere in the namespace
* Less common, but good to know:
  * `protected`: like `private`, but also accessible by the *inheritors* of the class
  * `virtual`: accessible and *overridable* by inheritors

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

```csharp
class Student
{
  int id;
  private string name;
  public string address;
}
```

</div>
</div>

---

* Continuing on the class in the previous example: if we follow the `student` variable with `.`, Visual Studio IntelliSense will only suggest the `address` variable, because it was the only `public` variable of the `Student` class!

  ![](imgs/7%20Classes%20and%20Objects_3.png)

## Classes: An example

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

```csharp
class Student
{
  public int id;
  public string name;
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    Student student1 = new Student();
    Student student2 = new Student();
    
    student1.id = 22225555;
    student1.name = "Johannes Kantola";
    student2.id = 44441111;
    student2.name = "Rene Orosz";
    
    Console.WriteLine(student1.name);
      // Outputs Johannes Kantola
  }
}
```

</div>
</div>

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

1) Create a console application that has a class `User` that contains two fields: `string userName` and `string password`
2) Create a main loop where the user is asked repeatedly for a new username and password. The values are stored in a new `User` instance and that instance is saved to a list of users
3) Print all stored usernames every time a new user is created

## Class methods

* As mentioned in [Lecture 6](6-methods), we can create methods inside of our classes:

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

```csharp
class Person
{
  public string firstName;
  public string lastName;
  public string FullName()
  {
    return firstName + " " + lastName;
  }
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    Person someDude = new Person();
    someDude.firstName = "Johannes";
    someDude.lastName = "Kantola";
    Console.WriteLine(someDude.FullName());
    // Outputs Johannes Kantola
  }
}
```

</div>
</div>

* If the method is public, it can be called from outside of the class

## Constructors

* Constructors are class methods which are called once the object is initialized
* Constructors are created by creating a class method with the same name as the class:

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

```csharp
class User
{
  public User()
  {
    Console.WriteLine
      ("New user created!");
  }
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    User user = new User();
    // Outputs "New user created!"
  }
}
```

</div>
</div>

* ***Note:*** In Visual Studio, just write `ctor` and press tab twice to quickly create a constructor!

## Constructors with parameters

* You can pass in parameters to the constructor at initialization:

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

```csharp
class Car
{
  private string model;
  private int year;
  private int doors;

  public Car(string modelName, int modelYear)
  {
    model = modelName;
    year = modelYear;
    doors = 5;
  }
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    Car lada = new Car("Niva", 1984);
    Car ford = new Car("Focus", 2010);
    // Both cars have 5 doors by default
  }
}
```
</div>
</div>

## Exercise 2
<!--_class: "exercise invert" -->

1) Create a console application with a class Animal, that contains
   * two strings, `name` and `sound`
   * a method `Greet()` that prints `<name> says <sound>!` (without the angled brackets)
2) Create a few animals with different names and sounds
3) Call their greet methods from the main program

## Properties

* When working with C#, you will eventually see  [properties](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties) being used at some point
* They are fields with defined `get` and `set` ***accessors***
  * These accessors are often referred to as a ***getter*** and a ***setter***
* Properties allow the manipulation of private fields from outside of the class:

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

```csharp
class User
{
  private int id;
  public int Id
  {
    get { return id; }
    set { id = value; }
  }
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    User admin = new User();
    admin.Id = 12345678;
    Console.WriteLine(admin.Id);
    // This outputs 12345678
  }
}
```

### Auto Properties

* Auto properties are a shorthand version of the same:

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

```csharp
class User
{
  public int Id { get; set; }
}
```

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    User admin = new User();
    admin.Id = 12345678;
    Console.WriteLine(admin.Id);
    // This outputs 12345678
  }
}
```

</div>
</div>

* ***Note:*** In Visual Studio, just write `prop` and press tab twice to quickly create an auto property

### Why properties?

* Why use properties if we could just use public fields?
* We don't always want to expose the exact same variable that is used inside the class to outside
* Properties allow class fields to be *__read-only__* or  *__write-only__*:
  ```csharp
  public int Id { get; }                    // This field is read-only
  public int Password { private get; set; } // This field is write-only
  ```
* Also, we can add whatever functionality we want to getters and setters, which makes properties a very flexible feature
  * Don't know when a property is being changed? Just print its value to the console in the setter.
* Properties are supported in *__interfaces__*, while fields are not
  * We will cover interfaces later in [Lecture 9](9-interfaces#interfaces)

## Value and Reference Types

* See the example below. If this program is executed, what will be the output?
* `int`, `double`, `char` and other primitive data types are of the *__value type__*
  * The variable stores the *__actual data__* in memory
  * Every copy of the variable will be stored in a separate location

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

```csharp
class Program{
  static void Main(string[] args)
  {
    int user = 1;
    int otherUser = user;
    user = 2;
    Console.WriteLine("Value of otherUser: " + otherUser);
  }
}
```

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

![w:400px](imgs/7%20Classes%20and%20Objects_4.png)

</div>
</div>

---

* Another example: When this program is executed, what will be the output?
* `string`, `Array` and Classes are of the *__reference type__
  * The variable stores ***the address of the data*** being stored in memory
  * Every copy of the variable points to the same ***address***

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

```csharp
class Program
{
  static void Main(string[] args)
  {
    User user = new User();
    user.id = 1;
    User otherUser = user;
    user.id = 2;
    Console.WriteLine(
      "Value of otherUser.id: " + otherUser.id);
  }
}
```

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

```csharp
class User
{
  public int id;
}
```

![](imgs/7%20Classes%20and%20Objects_5.png)

</div>
</div>

---

![](imgs/7%20Classes%20and%20Objects_6.png)

<!-- Location in memory

int userId = 42;

int otherUserId = userId;

| 42 |
| :-: |
| 42 |

Changing the value in the object will affect all variables referencing it!

| points to |
| :-: |
| points to |

User user = new User(42);

User otherUser = user;

| user { id = 42 } |
| :-: | -->

## Exercise 3
<!--_class: "exercise invert" -->

1) Classes can be stored in a separate file. To quickly create a new class in Visual Studio: right mouse click your project name (not the solution!) in Solution Explorer *->  Add -> Class...*
   * Name your class `TestClass`.
2) Back in your main method, create an instance of `TestClass`. The compiler should not give any errors.
3) Now rename the namespace that your `TestClass` is in to `TestNamespace`. Go back to your main method. The `TestClass` instantiation should not work anymore. Try to fix the issue without going back to `TestClass`!

<!-- ## Exercise 4

Modify previous solution by using methods and class. -->

