0% found this document useful (0 votes)
2 views

working-with-class-hierarchies-slides

The document discusses class hierarchies in object-oriented programming, focusing on inheritance, polymorphism, abstract and sealed classes, and extension methods. It explains how inheritance allows for code reuse and the establishment of relationships between classes, while polymorphism enables derived classes to alter base class implementations. Additionally, it covers the creation of abstract classes that cannot be instantiated, the use of sealed classes to prevent inheritance, and the implementation of extension methods to add functionality to existing classes.

Uploaded by

nouhaila.naamane
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

working-with-class-hierarchies-slides

The document discusses class hierarchies in object-oriented programming, focusing on inheritance, polymorphism, abstract and sealed classes, and extension methods. It explains how inheritance allows for code reuse and the establishment of relationships between classes, while polymorphism enables derived classes to alter base class implementations. Additionally, it covers the creation of abstract classes that cannot be instantiated, the use of sealed classes to prevent inheritance, and the implementation of extension methods to add functionality to existing classes.

Uploaded by

nouhaila.naamane
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 59

Working with

Class Hierarchies

Gill Cleeren
CTO Xpirit Belgium

@gillcleeren
Overview
Adding inheritance
Working with polymorphism
Exploring sealed and abstract classes
Using extension methods
Adding Inheritance
“We have in fact different types of products.
They behave rather similar but based on the
type, they will be differences.

Can we build this into the application?”


Different Types of Products

Product

Boxed product

Fresh boxed product


What are we doing here?
Organizing classes

Makes it easier to understand what


they will ‘inherit’ from another class

This is inheritance, an important


OOP pillar
Introducing Inheritance

Relation between classes

Allow reuse of functionalities of base (parent) class for derived


(child) class

Creates the “Is-A” relation

Access to members is controlled using access modifiers

Improves maintainability by avoiding code duplication


Inheritance Terminology

Product
Parent class
Base class
Superclass

Boxed product
Child class
Derived or extended class
Subclass

Fresh boxed product


Can be multiple levels deep
Class can only have one
direct parent
public class BaseClass
{
}

public class DerivedClass: BaseClass


{
}

Base and Derived Classes


Notice the :
Creating the Base and Derived Classes

Product.cs BoxedProduct.cs

public class Product


{ public class BoxedProduct : Product
public void UseProduct(int items) {
{
} }
}
BoxedProduct newProduct = new BoxedProduct();
newProduct.UseProduct(10);

Using the BoxedProduct


Has access to members of the base Product class
Depends on access modifier though
The Access Modifiers Revisited

public private protected


Accessing the Base Class Members

public class Product public class BoxedProduct: Product


{ {
public string name; public void
DisplayBoxedProductDetails()
public void DisplayDetails() {
{ Console.WriteLine(name);
}
} }
}
Working with private

public class Product public class BoxedProduct: Product


{ {
private string name; public void
DisplayBoxedProductDetails()
public void DisplayDetails() {
{ Console.WriteLine(name);//error
}
} }
}
Using the protected Access Modifier

public class Product public class BoxedProduct: Product


{ {
protected string name; public void
DisplayBoxedProductDetails()
public void DisplayDetails() {
{ Console.WriteLine(name);
}
} }
}
Extending the Derived Class

Product.cs BoxedProduct.cs

public class BoxedProduct : Product


public class Product {
{ private int AmountInBox;

public void UseProduct(int items) public void UseBoxedProduct(int


{ items)
} {
} }
}
Inheritance Is Transitive
Child class will inherit from all ancestors
(multiple levels)
“I think we’ll have products that we store per
item, some come boxed, some are bulk
products and yes, we also have fresh
products which expire quickly.”
Demo

Adding inheritance
Creating the different product classes
Inheritance and Constructors

Product

BoxedProduct bp = new BoxedProduct(); Boxed product


public class BoxedProduct : Product
{

public BoxedProduct(int id, string name, string? description, Price price, int
maxAmountInStock, int amountPerBox) : base(id, name, description, price,
UnitType.PerBox, maxAmountInStock)
{
AmountPerBox = amountPerBox;
}
}

Calling the Base Constructor with Parameters


Base constructor needs to get values for its constructor and will execute before the derived
class constructor executes
Uses the base keyword, passing in list of arguments
Everything IS AN object
All types derive from System.Object

Has a parameterless constructor

All types inherit a few members like


ToString()
Inheriting from System.Object

System.Object

Product

Boxed product
Demo

Inheriting from System.Object


Working with Polymorphism
We may have a
problem…
What if the behavior is different?

Derived may want to change an


existing base implementation
Introducing Polymorphism

Poly and morph > “many-shaped”

Allow treating objects of derived class as base class object

Based on virtual and override keywords

Override base class method with new implementation

Parameter lists need to be the same, otherwise overloading


The “Is-A” Relation

BoxedProduct Product
Is A
Product p1 = new BoxedProduct();
Product p2 = new FreshProduct();
p1.UseProduct(10);
p2.UseProduct(8);

Using a Base Reference


We invoke the UseProduct() on the base Product class
BoxedProduct boxedProduct = new BoxedProduct();

SaveProduct(boxedProduct);

public void SaveProduct(Product p)


{

Using Implicit Conversions


BoxedProduct boxedProduct = new BoxedProduct();
Product product = new Product();

Product[] products = new Product[10];

products[0] = product;
products[1] = boxedProduct;

Creating an Array of Products


Using the Base Reference

Product

UseProduct()

P B F P F B P
BoxedProduct

FreshProduct
Adding Polymorphism
Using virtual and override

Product BoxedProduct

public class BoxedProduct: Product


public class Product
{
{
public virtual void UseProduct
public override void UseProduct
(int items)
(int items)
{
{
//base implementation
//custom implementation
}
}
}
}
How does C# know which
implementation to use?
The most specific implementation
will be selected based on the type of
the object!
Looping over an Array of Product References

Product
Array of Product references
virtual UseProduct()

P P P P P P P
BoxedProduct

override UseProduct()

P B F P F B P
FreshProduct
Actual objects
Demo

Working with polymorphism


Product product = new BoxedProduct();

product.UseBoxedProduct();//error

Unavailable Methods
public void SaveProduct(Product p)
{
BoxedProduct bp = (BoxedProduct)p;//explicit cast which can be dangerous

if (p is BoxedProduct)
{

}
}

Using the is Keyword


public static void SaveProduct(Product p)
{
BoxedProduct? bp = p as BoxedProduct;

if (bp != null)
{
}
}

Using the as Keyword


public static void SaveProduct(object o)
{
string p = o.ToString();
}

Working with object


Explicitly calling the Base Implementation

public override void UseProduct(int items)


{
int smallestMultiple = 0;
int batchSize;

while (true)
{
smallestMultiple++;
if (smallestMultiple * AmountPerBox > items)
{
batchSize = smallestMultiple * AmountPerBox;
break;
}
}

base.UseProduct(batchSize);

}
public class Product
{
public virtual void UseProduct(int items)
{
//base implementation
}
}
public class BoxedProduct: Product
{
public void UseProduct(int items)
{
//custom implementation
}
}

Omitting the override Keyword


Hides the base implementation, known as shadowing
Triggers compiler warning
public class Product
{
public virtual void UseProduct(int items)
{
//base implementation
}
}
public class BoxedProduct: Product
{
public new void UseProduct(int items)
{
//custom implementation
}
}

Adding the new Keyword


Clears the compiler warning
Explicit about the intention
Exploring Abstract and Sealed classes
“I’m wondering… Should it still be possible to
create a Product instance?”
Introducing Abstract Classes

Can’t be instantiated but can be inherited

Contains shared functionality for its child classes

Can define abstract methods, without implementation

Child classes can be instantiated (if not declared abstract too)

Based on abstract keyword


Creating and Using an Abstract Class
Instantiating won’t work

Product Program.cs

public abstract class Product


{
public virtual void UseProduct
(int items)
Product p1 = new Product();//error
{
//base implementation
}
}
Product p1 = new BoxedProduct();

This Will Work!


Base reference points to inheriting class
public abstract class Product
{
public abstract void UseProduct(int items);
}

Adding abstract Methods


Don’t have an implementation
Must be overridden in inheriting types (otherwise, inheritor becomes abstract too)
virtual methods don’t need to receive an override in the inheriting type
Demo

Making the Product class abstract


public sealed class Product
{}

public class BoxedProduct: Product // error


{}

Making a Class sealed


Inheriting isn’t allowed
Useful if creating libraries that you want to protect
Demo

Making use of sealed classes


Using Extension Methods
We may want to add extra
functionality to a class
Inherit from existing class

Change the original

But what if we don’t have access? Or


it’s sealed?

Create an extension method


public sealed class Product
{
}

public static class ProductExtensions


{

public static double RemoveProduct(this Product product)


{
}
}

Adding an Extension Method


Allow to “add” methods on any type, even part of .NET or written by someone else
Must be static inside a static class and requires use of this
Type is the type that will be extended
Product p1 = new Product();

p1.RemoveProduct();

Using an Extension Method


Demo

Adding and using an extension method


Inheritance allows us to move member to
the base type
Summary Inheriting types can extend the base class
and use its functionality and data
Access modifiers control what can be
accessed by inheriting classes
Polymorphism allows to create different
version of method in inheriting types
Using extension methods, all types can be
extended with extra functionality
Up Next:

Reusing Code through Interfaces

You might also like