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

Chapter 15 Slides

Chapter 15 of Murach's C# (8th Edition) focuses on working with interfaces and generics, covering the development and use of .NET interfaces, distinguishing them from abstract classes, and implementing generic interfaces. It provides examples of interface implementation, including methods for cloning and displaying objects, and introduces a CustomList class that utilizes generics. Additionally, the chapter discusses constraints in generics and the implementation of IEnumerable<T> and IPersistable<T> interfaces.

Uploaded by

lowemorgan98
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Chapter 15 Slides

Chapter 15 of Murach's C# (8th Edition) focuses on working with interfaces and generics, covering the development and use of .NET interfaces, distinguishing them from abstract classes, and implementing generic interfaces. It provides examples of interface implementation, including methods for cloning and displaying objects, and introduces a CustomList class that utilizes generics. Additionally, the chapter discusses constraints in generics and the implementation of IEnumerable<T> and IPersistable<T> interfaces.

Uploaded by

lowemorgan98
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 36

Murach’s C# (8th Edition)

Chapter 15

How to work
with interfaces
and generics

© 2023, Mike Murach & Associates, Inc. C15, Slide 1


Objectives
Applied
1. Use .NET interfaces as you develop the classes for an app.
2. Develop and use your own interfaces.

Knowledge
3. Distinguish between an interface and an abstract class.
4. Describe the use of the .NET ICloneable, IComparable<T>, and
IEnumerable<T> interfaces.
5. In general terms, describe the use of default methods as well as
static fields and methods in interfaces.
6. In general terms, describe the use of generic interfaces.

Murach’s C# (8th Edition) C15, Slide 2


A Product class that implements
the IDisplayable interface
public class Product : IDisplayable
{
public Product() { }

public Product(string code, string description,


decimal price) =>
(Code, Description, Price) =
(code, description, price);

public string Code { get; set; } = "";


public string Description { get; set; } = "";
public decimal Price { get; set; }

public string GetDisplayText(string sep) =>


$"{Code}{sep}{Description}{sep}{Price.ToString("c")}";
}

Murach’s C# (8th Edition) C15, Slide 3


Code that uses the IDisplayable interface
IDisplayable product =
new Product("C#", "Murach's C#", 59.50m);
Debug.WriteLine(product.GetDisplayText("\n"));

Murach’s C# (8th Edition) C15, Slide 4


A comparison of interfaces and abstract classes
 Both interfaces and abstract classes can provide signatures for
properties and methods that a class must implement.
 Both interfaces and abstract classes can implement some or all of
their properties and methods.
 An abstract class can use instance variables and constants as well
as static variables and constants.
 An interface can only use static variables and constants.
 A class can inherit only one class (including abstract classes), but
a class can implement more than one interface.

Murach’s C# (8th Edition) C15, Slide 5


An interface that defines one method
public interface IDisplayable
{
string GetDisplayText(string sep);
}

Murach’s C# (8th Edition) C15, Slide 6


An interface that defines two methods
and a property
public interface IPersistable
{
object Read(string id);
bool Save(object o);
bool HasChanges { get; set; }
}

Murach’s C# (8th Edition) C15, Slide 7


An interface that inherits two interfaces
public interface IDataAccessObject :
IDisplayable, IPersistable
{
// add additional members here
}

Murach’s C# (8th Edition) C15, Slide 8


An interface that defines a default method
public interface IDisplayable
{
string GetDisplayText(string sep) =>
ToString() + sep;
}

Murach’s C# (8th Edition) C15, Slide 9


A class that uses the default method
public class Product : IDisplayable
{
// This doesn't override the GetDisplayText() method.
// It uses the GetDisplayText() method defined
// by the interface.
}

Murach’s C# (8th Edition) C15, Slide 10


A class that overrides the default method
public class Product : IDisplayable
{
...
public string GetDisplayText(string sep) =>
$"{Code}{sep}{Description}{sep}{Price.ToString("c")}";
}

Murach’s C# (8th Edition) C15, Slide 11


An interface that defines a static method
and a static field
public interface IPrintable
{
static string terminator = "\r\n";
static string Print(IDisplayable d) =>
d.GetDisplayText(terminator);
}

Murach’s C# (8th Edition) C15, Slide 12


Code that calls a static method from an interface
IDisplayable product =
new Product("C#", "Murach's C#", 59.50m);
string printString = IPrintable.Print(product);

Murach’s C# (8th Edition) C15, Slide 13


Code that implements interfaces
A Product class that implements ICloneable
public class Product : ICloneable

A Product class that implements two interfaces


public class Product : ICloneable, IDisplayable

Murach’s C# (8th Edition) C15, Slide 14


A class that inherits a class
and implements two interfaces
public class Book : Product, ICloneable, IDisplayable

Murach’s C# (8th Edition) C15, Slide 15


The Quick Actions menu for an interface name

Murach’s C# (8th Edition) C15, Slide 16


The code that’s generated
when you implement the interface
public object Clone()
{
throw new NotImplementedException();
}

Murach’s C# (8th Edition) C15, Slide 17


The code that’s generated
when you explicitly implement the interface
object ICloneable.Clone()
{
throw new NotImplementedException();
}

Murach’s C# (8th Edition) C15, Slide 18


The code for the cloneable Product class
public class Product : IDisplayable, ICloneable
{
public Product() { }

public Product(string code, string description,


decimal price) =>
(Code, Description, Price) =
(code, description, price);

public string Code { get; set; } = "";


public string Description { get; set; } = "";
public decimal Price { get; set; }

public string GetDisplayText(string sep) =>


$"{Code}{sep}{Description}{sep}{Price.ToString("c")}";

public object Clone() =>


new Product(Code, Description, Price);
}

Murach’s C# (8th Edition) C15, Slide 19


Code that creates and clones a Product object
Product p1 = new("RDA", "Murach's R for Data Analysis",
59.50m);
Product p2 = (Product)p1.Clone();

p2.Code = "PDA";
p2.Description = "Murach's Python for Data Analysis";

Debug.WriteLine(p1.GetDisplayText("\n") + "\n");
Debug.WriteLine(p2.GetDisplayText("\n") + "\n");

The output that’s displayed


RDA
Murach's R for Data Analysis
$59.50

PDA
Murach's Python for Data Analysis
$59.50

Murach’s C# (8th Edition) C15, Slide 20


A CreateList() method that uses an interface
as a parameter
public static List<object> CreateList(ICloneable obj,
int count)
{
List<object> objects = new();
for (int i = 0; i < count; i++)
{
object o = obj.Clone();
objects.Add(o);
}
return objects;
}

Murach’s C# (8th Edition) C15, Slide 21


A WriteToDebug() method that uses an interface
as a parameter
public static void WriteToDebug(IDisplayable d) =>
Debug.WriteLine(d.GetDisplayText("\n") + "\n");

Murach’s C# (8th Edition) C15, Slide 22


Code that uses the CreateList and
WriteToDebug methods
Product product = new("C#", "Murach's C#", 59.50m);
List<object> products = CreateList(product, 3);
foreach (Product p in products)
{
WriteToDebug(p);
}

The output that’s displayed


C#
Murach's C#
$59.50

C#
Murach's C#
$59.50

C#
Murach's C#
$59.50

Murach’s C# (8th Edition) C15, Slide 23


A CustomList<T> class that uses generics
public class CustomList<T>
{
private List<T> list = new();
// an Add() method
public void Add(T item) => list.Add(item);
// a read-only indexer
public T this[int i] => list[i];
// a read-only property
public int Count => list.Count;
// the ToString() method
public override string ToString()
{
string listString = "";
foreach (T item in list)
{
listString += item?.ToString() + "\n";
}
return listString;
}
}

Murach’s C# (8th Edition) C15, Slide 24


Code that uses the CustomList<T> class (Test 1)
Debug.WriteLine("List 1 - ints");
CustomList<int> list1 = new();
int int1 = 11;
int int2 = 7;
list1.Add(int1);
list1.Add(int2);
Debug.WriteLine(list1.ToString());

Output from Test 1


List 1 - ints
11
7

Murach’s C# (8th Edition) C15, Slide 25


Code that uses the CustomList<T> class (Test 2)
Debug.WriteLine("List 2 - Products");
CustomList<Product> list2 = new();
Product p1 = new("JAVA", "Murach's Java Programming",
59.50m);
Product p2 = new("C#", "Murach's C#", 59.50m);
list2.Add(p1);
list2.Add(p2);
Debug.Write(list2.ToString());

Output from Test 2


List 2 - Products
JAVA Murach's Java Programming $59.50
C# Murach's C# $59.50

Murach’s C# (8th Edition) C15, Slide 26


A class that implements
the IComparable<T> interface
public class Product : IComparable<Product>
{
public string Code { get; set; } = "";
public string Description { get; set; } = "";
public decimal Price { get; set; }

// other members

public int CompareTo(Product? other) =>


this.Code.CompareTo(other?.Code);
}

Murach’s C# (8th Edition) C15, Slide 27


Code that uses the class
Product p1 = new("JAVA", "Murach's Java Programming",
59.50m);
Product p2 = new("C#", "Murach's C#", 59.50m);
int compareValue = p1.CompareTo(p2);
if (compareValue > 0)
Debug.WriteLine("p1 is greater than p2");
else if (compareValue < 0)
Debug.WriteLine("p1 is less than p2");
else if (compareValue == 0)
Debug.WriteLine("p1 is equal to p2");

Murach’s C# (8th Edition) C15, Slide 28


Values that can be returned
by the CompareTo() method
-1, 0, 1

Murach’s C# (8th Edition) C15, Slide 29


A class that uses constraints
public class CustomList<T> where T: class, IComparable<T>
{
private List<T> list = new();
// an Add() method that keeps the list sorted
public void Add(T newitem)
{
for (int i = 0; i < list.Count; i++)
{
var item = list[i];
int compare = newitem.CompareTo(item);
if (compare <= 0) // new item less than or
{ // equal to current item
list.Insert(i, newitem);
return;
}
}
list.Add(newitem);
}
...
}

Murach’s C# (8th Edition) C15, Slide 30


Keywords that can be used to define constraints
class
struct
new()
System.Enum
System.Delegate

Murach’s C# (8th Edition) C15, Slide 31


A class that’s constrained to value types
public class StructList<T> where T: struct

Another class that uses constraints


public class ProductList<T> where T: Product,
IComparable<T>, new()

Murach’s C# (8th Edition) C15, Slide 32


A class that implements IEnumerable<T>
public class CustomList<T> : IEnumerable<T>
{
private List<T> list = new();

// other members

public IEnumerator<T> GetEnumerator()


{
foreach (T item in list)
{
yield return item;
}
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}

Murach’s C# (8th Edition) C15, Slide 33


Code that uses the CustomList class
Product p1 = new("JAVA", "Murach's Java Programming",
59.50m);
Product p2 = new("C#", "Murach's C#", 59.50m);
CustomList<Product> list = new();
list.Add(p1);
list.Add(p2);
foreach (Product p in list)
{
Debug.WriteLine(p.ToString());
}

Murach’s C# (8th Edition) C15, Slide 34


An interface named IPersistable<T>
that uses generics
public interface IPersistable<T>
{
T Read(string id);
bool Save(T obj);
bool HasChanges { get; set; }
}

Murach’s C# (8th Edition) C15, Slide 35


A class that implements IPersistable<T>
public class Customer : IPersistable<Customer>
{
// other members

public bool HasChanges {


get => throw new NotImplementedException();
set => throw new NotImplementedException();
}

public Customer Read(string id)


{
throw new NotImplementedException();
}

public bool Save(Customer obj)


{
throw new NotImplementedException();
}
}

Murach’s C# (8th Edition) C15, Slide 36

You might also like