You are on page 1of 25

Advanced Programming (C#) (CSE 222)

Lecture 7

Polymorphism & Abstract & Interface


Delegate

Prepared by:
Dr. Ahmed Samy Moursi
Computer Science and Engineering Department
https://ahmedhashwa.github.io/
Quote of the day (1)

Lecture 7
CSE 321 Object Oriented Programming (C#) 2
Agenda

Lecture 7
CSE 321 Object Oriented Programming (C#) 3
Polymorphism
Polymorphism

Lecture 7
◼ Polymorphism in C# is a concept in object-oriented programming that
allows objects to have various forms.
◼ Definition: Polymorphism is derived from two Greek words: “poly”
meaning many, and “morph” meaning forms. Thus, polymorphism is
the ability of an object to take on many forms.
◼ Types: There are two types of polymorphism in C#: compile-time
polymorphism (also known as static or early binding) and runtime
polymorphism (also known as dynamic or late binding).
◼ Compile-Time Polymorphism: This is achieved through method
overloading and operator overloading. Method overloading allows a
class to have multiple methods with the same name but different
parameters, while operator overloading allows redefining the way an
operator works for a class.
◼ Demo on operator overloading in Point class

CSE 321 Object Oriented Programming (C#) 5


Polymorphism

Lecture 7
◼ Runtime Polymorphism: This is achieved through method
overriding and virtual methods. Method overriding allows a subclass
to provide a specific implementation of a method that is already
provided by its parent class.
◼ Benefits: Polymorphism increases the flexibility and interoperability of
programs. It allows objects of different types to be treated as objects of
a parent type, leading to simpler and more efficient code.

CSE 321 Object Oriented Programming (C#) 6


Lecture 7
Polymorphic vs Non-Polymorphic Inheritance
◼ If a method in the parent class has the keyword virtual then the child
class can use the keyword override with the same signature of that
method to change the way it is implemented. Hence, when an object of
the child class is referenced by the parent class, the overridden method
in the child class is called. This is called polymorphic inheritance.
◼ If the method in the parent class doesn’t have the keyword virtual then
the child class cannot use the keyword override but can use the new
keyword optionally and when an object of the child class is
referenced by the parent class, the method in the parent class is called.
This is called non-polymorphic inheritance.
◼ Simply put, polymorphic inheritance respects the object or the
right-side of the assignment while non-polymorphic inheritance
respects the reference or the left-side of the assignment.

CSE 321 Object Oriented Programming (C#) 7


Quote of the day (2)

Lecture 7
CSE 321 Object Oriented Programming (C#) 8
Abstract Classes
and Interfaces
Abstract Classes

Lecture 7
◼ Sometimes the parent class is a conceptual idea that doesn’t exist or is
incomplete.
◼ For example, in the Shape hierarchy of the last lecture there are many
types inheriting from Shape but there is no “Shape” only the type must
be specific to exist such as Circle or Cube.
◼ Hence the root class may be an abstract class and that prohibit making
objects of that class.
◼ Also, you can have abstract methods for which only the signature
exists with no body so that the inheriting class must implement that
method.
◼ An abstract method must be defined in an abstract class, but an
abstract class may not have an abstract method.

CSE 321 Object Oriented Programming (C#) 10


Interfaces

Lecture 7
◼ An interface in C# is a contract that defines the signature of the
functionality.
◼ So, it contains only the declaration of the methods, and properties, but
not the implementation.
◼ An interface is implemented by any class or struct that provides the
necessary functionality. Multiple interfaces can be implemented by a
single class.
◼ Interfaces can be inherited from other interfaces. This provides a way
to achieve multiple inheritances in C#, which isn’t directly possible
because C# doesn’t support multiple inheritance through classes.
◼ If a class implements two interfaces that contain a member with the
same signature, then implementing that member on the class will
cause both interfaces to use that member as their implementation.
◼ C# provides a way to implement each interface member separately by
implementing interface members explicitly.
◼ The interface name usually starts with capital I beside the PascalName
like IComparable.
CSE 321 Object Oriented Programming (C#) 11
Delegates
Delegate

Lecture 7
◼ A delegate is an object that knows how to call a method.
◼ A delegate type defines the kind of method that delegate instances can call.

Specifically, it defines the method’s return type and its parameter types. The
following defines a delegate type called Transformer:
delegate int Transformer (int x);
◼ Transformer is compatible with any method with an int return type and a single int

parameter, such as this:


int Square (int x) => x * x;
◼ Here’s a complete example:
◼ Transformer t = Square; // Create delegate instance

int result = t.Invoke(3); // Invoke delegate


Console.WriteLine(result); // 9
int Square(int x) => x * x;
delegate int Transformer (int x); // Delegate type declaration
◼ The statement: Transformer t = Square;

is shorthand for: Transformer t = new Transformer (Square);

CSE 321 Object Oriented Programming (C#) 13


Delegate

Lecture 7
◼ A delegate type can contain generic type parameters:
public delegate T Transformer<T> (T arg);
◼ With this definition, we can write a generalized Transform utility method that works
on any type:
◼ int[] values = { 1, 2, 3 };
Transform(values, Square); // Hook in the Square method
foreach (int i in values)
Console.Write(i + " "); // 1 4 9
void Transform<T>(T[] values, Transformer<T> t)
{
for (int i = 0; i < values.Length; i++)
values[i] = t(values[i]);
}
int Square(int x) => x * x;
int Cube(int x) => x * x * x;
delegate T Transformer<T>(T x);

CSE 321 Object Oriented Programming (C#) 14


Writing Plug-In Methods with Delegates

Lecture 7
◼ A delegate variable is assigned a method at runtime. This is useful for writing plug-
in methods.
◼ In this example, we have a utility method named Transform that applies a
transform to each element in an integer array.
◼ The Transform method has a delegate parameter, which you can use for specifying
a plug-in transform:
◼ int[] values = { 1, 2, 3 };
Transform(values, Square); // Hook in the Square method
foreach (int i in values)
Console.Write(i + " "); // 1 4 9
void Transform(int[] values, Transformer t)
{
for (int i = 0; i < values.Length; i++)
values[i] = t(values[i]);
}
int Square(int x) => x * x;
int Cube(int x) => x * x * x;
delegate int Transformer(int x);
CSE 321 Object Oriented Programming (C#) 15
Writing Plug-In Methods with Delegates

Lecture 7
◼ We can change the transformation just by changing Square to Cube in the second
line of code.
◼ Our Transform method is a higher-order function because it’s a function that takes
a function as an argument. (A method that returns a delegate would also be a
higher-order function.)

CSE 321 Object Oriented Programming (C#) 16


Multicast Delegates

Lecture 7
◼ All delegate instances have multicast capability.
◼ This means that a delegate instance can reference not just a single target method
but also a list of target methods. The + and += operators combine delegate
instances:
SomeDelegate d = SomeMethod1;
d += SomeMethod2;
◼ The last line is functionally the same as the following:
d = d + SomeMethod2;
◼ Invoking d will now call both SomeMethod1 and SomeMethod2. Delegates are
invoked in the order in which they are added.
◼ The - and -= operators remove the right delegate operand from the left delegate
operand:
d -= SomeMethod1;
◼ Invoking d will now cause only SomeMethod2 to be invoked.
◼ Delegates are immutable, so when you call += or -=, you’re in fact creating a new
delegate instance and assigning it to the existing variable.

CSE 321 Object Oriented Programming (C#) 17


Multicast Delegates

Lecture 7
◼ If a multicast delegate has a nonvoid return type, the caller receives the return
value from the last method to be invoked.
◼ The preceding methods are still called, but their return values are discarded.
◼ For most scenarios in which multicast delegates are used, they have void return
types, so this subtlety does not arise.
◼ Example :
◼ Suppose that you wrote a method that took a long time to execute. That method
could regularly report progress to its caller by invoking a delegate. In this example,
the HardWork method has a ProgressReporter delegate parameter, which it invokes
to indicate progress

CSE 321 Object Oriented Programming (C#) 18


Multicast Delegates

Lecture 7
◼ public delegate void ProgressReporter(int percentComplete);
public class Util
{
public static void HardWork(ProgressReporter p)
{
for (int i = 0; i <= 10; i++)
{
p(i * 10); // Invoke delegate
System.Threading.Thread.Sleep(1000); // Simulate hard work
}
}
}
◼ To monitor progress, we can create a multicast delegate instance p, such that progress is
monitored by two independent methods:
◼ ProgressReporter p = WriteProgressToConsole;
p += WriteProgressToFile;
Util.HardWork(p);
void WriteProgressToConsole(int percentComplete)
=> Console.WriteLine($"{percentComplete/100.0:P0}");
void WriteProgressToFile(int percentComplete)
=> System.IO.File.WriteAllText("progress.txt",
percentComplete.ToString());

CSE 321 Object Oriented Programming (C#) 19


The Func and Action Delegates

Lecture 7
◼ With generic delegates, it becomes possible to write a small set of delegate types
that are so general they can work for methods of any return type and any
(reasonable) number of arguments.
◼ These delegates are the Func and Action delegates, defined in the System
namespace :
delegate TResult Func <out TResult> ();
delegate TResult Func <in T, out TResult> (T arg);
delegate TResult Func <in T1, in T2, out TResult> (T1 arg1, T2 arg2);
... and so on, up to T16
delegate void Action ();
delegate void Action <in T> (T arg);
delegate void Action <in T1, in T2> (T1 arg1, T2 arg2);
... and so on, up to T16

CSE 321 Object Oriented Programming (C#) 20


The Func and Action Delegates

Lecture 7
◼ These delegates are extremely general. The Transformer delegate in our previous
example can be replaced with a Func delegate that takes a single argument of type
T and returns a same-typed value:
public static void Transform<T>(T[] values, Func<T, T> transformer)
{
for (int i = 0; i < values.Length; i++)
values[i] = transformer(values[i]);
}
◼ Also, the report progress example can be replaced by Action.

CSE 321 Object Oriented Programming (C#) 21


Delegates Versus Interfaces

Lecture 7
◼ A problem that you can solve with a delegate can also be solved with an interface.
For instance, we can rewrite our original example with an interface called
ITransformer instead of a delegate:
int[] values = { 1, 2, 3 };
Util.TransformAll(values, new Squarer());
foreach (int i in values)
Console.WriteLine(i);
public interface ITransformer
{
int Transform(int x);
}
public class Util
{
public static void TransformAll(int[] values, ITransformer t)
{
for (int i = 0; i < values.Length; i++)
values[i] = t.Transform(values[i]);
}
}
class Squarer : ITransformer
{
public int Transform(int x) => x * x;
}

CSE 321 Object Oriented Programming (C#) 22


Delegates Versus Interfaces

Lecture 7
◼ A delegate design might be a better choice than an interface design if one or more
of these conditions are true:
◼ The interface defines only a single method.
◼ Multicast capability is needed.
◼ The subscriber needs to implement the interface multiple times.

CSE 321 Object Oriented Programming (C#) 23


Quote of the day (3)

Lecture 7
CSE 321 Object Oriented Programming (C#) 24
References

Lecture 7
◼ interface - C# Reference - C# | Microsoft Learn
◼ Introduction to delegates and events in C# - C# | Microsoft Learn
◼ C# 10 in a Nutshell: Chapter 4 Advanced C# Delegates

CSE 321 Object Oriented Programming (C#) 25

You might also like