# Inheritance

## Access Modifiers

One of the core ideas that OOP tries to promote is to make your classes into **black boxes**. That's because if you expose the implementation details of a class, other code that uses that class will be affected if you *change* those implementation details.

In contrast, everything we *want* to make accessible is part of the **public interface** of a class: it's what we want to expose to our users.

To create the black box and public interface of a class, we have **access modifiers**. If you recall, these are the ones we have available in C#:

* `public`
* `private`
* `protected`
* `internal`
* `protected internal`

### `public`

Makes a field/property/method **accessible everywhere**. You use `public` when you want your field/property/method to be part of the public interface of the class.

```cs
public class Customer
{
  public void Promote() {}
}

var customer = new Customer();
customer.Promote();
```

### `private`

Makes a field/property/method **only accessible inside the class**. You use `private` when you're dealing with the implementation details and so don't want to give open access.

```cs
public class Customer
{
  private int CalculateRating() {}

  public void Promote()
  {
    // Implementation details!
    if (CalculateRating() > 100)
    {
       // Do something...
    }
  }
}

var customer = new Customer();
customer.CalculateRating(); // fails
```

### `protected`

Makes a field/property/method **accessible from the class AND its derived classes**.

```cs
public class Customer
{
  public int CalculateRating() {}
}

public class VIP : Customer
{
  public void Promote()
  {
    // Access to implementation details!
    if (CalculateRating() > 1000)
    {
      // Do something...
    }
  }
}
```

**Pro tip**: `protected` is not good practice because it's not enough of a black box. Any derived classes still are granted access! For that reason, `private` is preferred over `protected`.

### `internal`

Makes a class itself **accessible only from the same assembly**. You use `internal` when a class you create is a useful implementation detail for all the classes in its assembly.

```cs
internal class RateCalculator {}

// In the same assembly: WORKS
var calc = new RateCalculator();

// In another assembly: FAILS
var calc = new RateCalculator();
```

### `protected internal`

Makes a field/property/method **accessible from the same assembly** OR **accessible from any derived classes**.

```cs
public class Customer
{
  protected internal void Weirdo() {}
}

// In another assembly: WORKS
var customer = new Customer();
customer.Weirdo();

// In a derived class: WORKS
public class VIP : Customer {}
var vip = new VIP();
vip.Weirdo();
```

**Pro tip**: This access modifier is really weird. You likely won't use it.

## Constructors and Inheritance

Suppose you create a `Vehicle` class and a derived `Car` class that inherits from `Vehicle`. There are 2 things to note about the `Vehicle` constructor:

1. Base class constructor is always executed *before* the derived class constructor.
2. Base class constructor is *never inherited* by the derived class.

In code, that means you have to explicitly create a new constructor for the derived class:

```cs
public class Vehicle
{
  private string _registrationNumber;

  public Vehicle(string registrationNumber)
  {
    _registrationNumber = registrationNumber;
    Console.WriteLine("Vehicle gets initialized first");
  }
}

public class Car : Vehicle
{
  public Car(string registrationNumber)
  {
    _registrationNumber = registrationNumber;
    Console.WriteLine("Car gets initialized second");
  }
}
```

There's 2 troubles with this though!

1. You can't initialize `_registrationNumber` in the `Car` constructor because it's a `private` field. This means it's not accessible in a derived class like `Car`.
2. The constructor for `Car` feels like repeated code. Is there a way to simplify this?

To solve this, we introduce the `base` keyword: it passes arguments to the base class constructor while *inside* the derived class.

```cs
public class Car : Vehicle
{
  public Car(string registrationNumber)
    : base(_registrationNumber)
  {
    // Initialize fields *specific* to the Car class here
    Console.WriteLine("Car gets initialized second");
  }
}
```

### Upcasting and Downcasting

**Upcasting** is converting a derived class to a base class, and **downcasting** is converting a base class to a derived class.

### Upcasting

Suppose you have a base class and derived class. To upcast, i.e., convert a derived class *to* its base class, C# does it using **implicit type conversion**.

```cs
public class Shape {}
public class Circle : Shape {}

Circle circle = new Circle();
Shape shape = circle; // upcasting
```

**Note**:

* `shape` and `circle` are actually the same object in memory (`shape == circle` returns `true`), but they have different views.
* `circle` can see all the `Circle` members *and* the `Shape` members.
* In contrast, `shape` can only see the `Shape` members.
* You'll see later how this is useful when we talk about polymorphism.

**Pro tip**: One common use case for upcasting is when you pass arguments to a function and/or constructor. When a parameter supports a base class, you know you can also *pass the derived class*, and it will be implicitly converted!

```cs
public class ImplicitCast
{
  private Shape _shape;
  public ImplicitCase(Shape shape)
  {
    _shape = shape;
  }
}

var obj = new ImplicitCast(new Circle());
```

### Downcasting

With downcasting, you must perform **explicit type conversion**, which is known as casting.

```cs
public class Shape {}
public class Circle : Shape {}

Shape shape = new Shape();
Circle circle = (Circle)shape; // downcasting
```

**Pro tip**: A common use case for downcasting is when you need access to a greater view of available fields/properties/methods. For example, maybe you have a generic `object`, but you believe it is a `Button`, and you want to use the `Button` members.

```cs
private void ButtonClick(object sender)
{
  sender.clickDetails; // not accessible
  var button = (Button) sender;
  button.clickDetails; // accessible
}
```

### The `as` keyword

When downcasting, you can't always guarantee it will work. That means there may be an `InvalidCastException` error, breaking the application if it's not handled.

To more elegantly solve this without creating an error, you use the `as` keyword:

```cs
Car car = (Car)shape; // throws error

Car car = shape as Car; // returns null if fails
if (car != null)
{
  // Do something...
}
```

### The `is` keyword

Alternatively, instead of `as` where you cast first and then find out if it failed, you can use `is` to check if it's possible to cast.

```cs
if (shape is Car)
{
  Car car = (Car)shape;
}
```

## Boxing and Unboxing

If you recall, there are value types and reference types.

Value types:

* Stored in stack where items in memory get removed immediately after they go out of scope.
* Stack also has more limited amount of memory.
* Examples: `int`, `bool`, `char`

Reference types:

* Stored in heap where items require a longer lifetime.
* Heap also has a lot more memory allocation.
* Examples: any classes like objects, arrays, strings

Additionally, we also know that `object` is the base class of *all* classes.

```cs
object obj = new Shape();
```

### Boxing

What happens if we implicitly convert a value type into an `object`? This is known as **boxing**:

```cs
object obj = 10;
```

Behind the scenes, the CLR boxes the value `10` and stores it in the *heap*. Then it places a reference to that object in the *stack*.

**Note**: Creating an object has a performance cost, so be aware of this.

### Unboxing

**Unboxing** is exactly what you think: after a value type has been boxed in a reference in the heap, you can extract the value and put it back in the stack by *casting* the reference.

```cs
object obj = 10;
int number = (int)obj;
```


---

# 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://notes.danfitz.com/csharp/csharpintermediate/3-inheritance.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.
