Polymorphism through Interfaces

Consider another example, as shown in Listing 8.2 with Output 8.1: IListable defines the members that a class needs to support if the ConsoleListControl class is to display it. As such, any class that implements IListable can use the ConsoleListControl to display itself. The IListable interface requires a read-only property, CellValues.

Listing 8.2: Implementing and Using Interfaces
1. public interface IListable
2. {
3.     // Return the value of each cell in the row
4.     string?[] CellValues { get; }
5. }
6.  
7. public abstract class PdaItem
8. {
9.     public PdaItem(string name)
10.     {
11.         Name = name;
12.     }
13.  
14.     public virtual string Name { getset; }
15. }
16.  
17. public class Contact : PdaItem, IListable
18. {
19.     public Contact(string firstName, string lastName,
20.         string address, string phone)
21.         : base(GetName(firstName, lastName))
22.     {
23.         FirstName = firstName;
24.         LastName = lastName;
25.         Address = address;
26.         Phone = phone;
27.     }
28.  
29.     public string FirstName { get; }
30.     public string LastName { get; }
31.     public string Address { get; }
32.     public string Phone { get; }
33.     public static string GetName(string firstName, string lastName)
34.         => $"{ firstName } { lastName }";
35.  
36.     public string[] CellValues
37.     {
38.         get
39.         {
40.             return new string[]
41.             {
42.                 FirstName,
43.                 LastName,
44.                 Phone,
45.                 Address
46.             };
47.         }
48.     }
49.  
50.     public static string[] Headers
51.     {
52.         get
53.         {
54.             return new string[] {
55.                 "First Name""Last Name    ",
56.                 "Phone       ",
57.                 "Address                       " };
58.         }
59.     }
60.     // ...
61. }
62.  
63. public class Publication : IListable
64. {
65.     public Publication(string title, string author, int year)
66.     {
67.         Title = title;
68.         Author = author;
69.         Year = year;
70.     }
71.  
72.     public string Title { get; }
73.     public string Author { get; }
74.     public int Year { get; }
75.  
76.     public string?[] CellValues
77.     {
78.         get
79.         {
80.             return new string?[]
81.             {
82.                 Title,
83.                 Author,
84.                 Year.ToString()
85.             };
86.         }
87.     }
88.  
89.     public static string[] Headers
90.     {
91.         get
92.         {
93.             return new string[] {
94.                 "Title                                                    "
95.                 "Author             "
96.                 "Year" };
97.         }
98.     }
99.  
100.     // ...
101. }
102.  
103. public class Program
104. {
105.     public static void Main()
106.     {
107.         Contact[] contacts = new Contact[]
108.         {
109.           new(
110.               "Dick""Traci",
111.               "123 Main St., Spokane, WA  99037",
112.               "123-123-1234"),
113.           new(
114.               "Andrew""Littman",
115.               "1417 Palmary St., Dallas, TX 55555",
116.               "555-123-4567"),
117.           new(
118.               "Mary""Hartfelt",
119.               "1520 Thunder Way, Elizabethton, PA 44444",
120.               "444-123-4567"),
121.           new(
122.               "John""Lindherst",
123.               "1 Aerial Way Dr., Monteray, NH 88888",
124.               "222-987-6543"),
125.           new(
126.               "Pat""Wilson",
127.               "565 Irving Dr., Parksdale, FL 22222",
128.               "123-456-7890"),
129.           new(
130.               "Jane""Doe",
131.               "123 Main St., Aurora, IL 66666",
132.               "333-345-6789")
133.         };
134.  
135.         // Classes are cast implicitly convertible to
136.         // their supported interfaces
137.         ConsoleListControl.List(Contact.Headers, contacts);
138.  
139.         Console.WriteLine();
140.  
141.         Publication[] publications = new Publication[3] {
142.             new(
143.                 "The End of Poverty: Economic Possibilities for Our Time",
144.                 "Jeffrey Sachs", 2006),
145.             new("Orthodoxy",
146.                 "G.K. Chesterton", 1908),
147.             new(
148.                 "The Hitchhiker's Guide to the Galaxy",
149.                 "Douglas Adams", 1979)
150.             };
151.         ConsoleListControl.List(
152.             Publication.Headers, publications);
153.     }
154. }
155.  
156. public class ConsoleListControl
157. {
158.     public static void List(string[] headers, IListable[] items)
159.     {
160.         int[] columnWidths = DisplayHeaders(headers);
161.  
162.         for(int count = 0; count < items.Length; count++)
163.         {
164.             string?[] values = items[count].CellValues;
165.             DisplayItemRow(columnWidths, values);
166.         }
167.     }
168.  
169.     /// <summary>Displays the column headers</summary>
170.     /// <returns>Returns an array of column widths</returns>
171.     private static int[] DisplayHeaders(string[] headers)
172.     {
173.         // ...
174.     }
175.  
176.     private static void DisplayItemRow(
177.         int[] columnWidths, string?[] values)
178.     {
179.         // ...
180.     }
181. }

Output 8.1
First Name  Last Name      Phone         Address
Dick        Traci          123-123-1234  123 Main St., Spokane, WA  99037
Andrew      Littman        555-123-4567  1417 Palmary St., Dallas, TX 55555
Mary        Hartfelt       444-123-4567  1520 Thunder Way, Elizabethton, PA 44444
John        Lindherst      222-987-6543  1 Aerial Way Dr., Monteray, NH 88888
Pat         Wilson         123-456-7890  565 Irving Dr., Parksdale, FL 22222
Jane        Doe            333-345-6789  123 Main St., Aurora, IL 66666
Title                                                    Author             Year
The End of Poverty: Economic Possibilities for Our Time  Jeffrey Sachs      2006
Orthodoxy                                                G.K. Chesterton    1908
The Hitchhiker's Guide to the Galaxy                     Douglas Adams      1979

In Listing 8.2, the ConsoleListControl can display seemingly unrelated classes (Contact and Publication). Any class can be displayed provided that it implements the required interface. As a result, the ConsoleListControl.List() method relies on polymorphism to appropriately display whichever set of objects it is passed. Each class has its own implementation of CellValues, and converting a class to IListable still allows the particular class’s implementation to be invoked.

{{ snackbarMessage }}
;