Download presentation
Presentation is loading. Please wait.
1
Interfaces and Generics
Based on Murach (ch 15) and Deitel 2012
2
Objectives Applied Use .NET interface(s) as you develop the classes for an application. Develop and use your own interfaces. Knowledge Distinguish between an interface and an abstract class. Describe the use of the .NET ICloneable IComparable<> IEnumerable<> interfaces. In general terms, describe the use of generic interfaces. `
3
Interface An interface consists of a set of signatures for one or more methods, properties, indexers, or events. An interface doesn’t provide an implementation for any of its members. Instead, it indicates what members must be defined by any class that implements the interface. By convention, interface names begin with the letter I to distinguish them from classes. To implement an interface, a class must name the interface on the class declaration, and it must provide an implementation for every member of the interface.
4
The IDisplayable interface
interface IDisplayable { string GetDisplayText(string sep); } No implementation
5
A Product class that implements the IDisplayable interface
public class Product : IDisplayable { public string Code { get; set; } public string Description { get; set; } public decimal Price { get; set; } public Product(string Code, string Description, decimal Price) this.Code = Code; this.Description = Description; this.Price = Price; } public string GetDisplayText(string sep) => this.Code + sep + this.Description + sep + this.Price.ToString("c");
6
Code that uses the IDisplayable interface
IDisplayable product = new Product( "CS15", "Murach's C# 2015", 56.50m); Console.WriteLine(product.GetDisplayText("\n")); Can be used
7
A comparison of interfaces and abstract classes
Both interfaces and abstract classes provide signatures for properties and methods that a class must implement. All of the members of an interface are abstract. In contrast, an abstract class can implement some or all of its members. A class can inherit only one class (including abstract classes), but a class can implement more than one interface. Interfaces can’t declare static members, but abstract classes can.
8
Commonly used .NET interfaces
Business classes need to implement it Starts with I (Microsoft style)
9
Common .NET interfaces for collections
10
.NET Interfaces The .NET Framework defines many interfaces that you can implement in your classes. However, many of these interfaces have been updated by the generic interfaces The ICollection interface inherits the IEnurnerable interface, which means that any class that implements ICollection must also implement IEnurnerable. Similarly, the IList and IDictionary interfaces inherit ICollection and IEnurnerable
11
The syntax for creating an interface
public interface InterfaceName { type MethodName(parameters); //method type Property Name //property { [get;] [set;] } ... } Unlike classes NO implementation NO access modifiers (all public) NO static
12
An interface that defines one method
public interface IDisplayable { string GetDisplayText(string sep); } An interface that defines 2 methods and 1 property public interface IPersistable object Read(string id); bool Save(object o); bool HasChanges get; set;
13
The syntax for creating an interface that inherits other interfaces
public interface InterfaceName : InterfaceName1 [, InterfaceName2]... { interface members... } Ex: an interface that inherits two interfaces public interface IDataAccessObject : IDisplayable, IPersistable // add additional members here
14
The syntax for implementing an interface
public class ClassName : [BaseClassName,] InterfaceName1[, InterfaceName2]... A Product class that implements ICloneable public class Product : ICloneable A Product class that implements two interfaces public class Product : ICloneable, IDisplayable A class that inherits a class and implements two interfaces public class Book : Product, ICloneable, IDisplayable Class is first
15
Interface Declaration
The declaration for an interface is similar to the declaration for a class. The only difference is that you use the interface keyword instead of the class keyword. Methods and properties that are declared within an interface can’t include implementation. As a result, method declarations and get and set accessors always end with a semicolon. You shouldn’t include any access modifiers on interface members. All members are considered to be public and abstract, and static in members aren’t allowed.
16
Peek Definition class Test : ICloneable { object ICloneable.Clone()
throw new NotImplementedException(); }
17
The code that’s generated when you implement the interface
public object Clone() { throw new NotImplementedException(); } The code that’s generated when you explicitly implement the interface object ICloneable.Clone()
18
ICloneable Interface
19
The code for the cloneable Product class
public class Product : IDisplayable, ICloneable { public string Code { get; set; } public string Description { get; set; } public decimal Price { get; set; } public Product(string Code, string Description,decimal Price) this.Code = Code; this.Description = Description; this.Price = Price; } public string GetDisplayText(string sep) => this.Code + sep + this.Description + sep + this.Price.ToString("c");
20
The code for the cloneable Product class cont.
public object Clone() { Product p = new Product(); p.Code = this.Code; p.Description = this.Description; p.Price = this.Price; return p; }
21
Code that creates and clones a Product object
Product p1 = new Product("BJWN", "Murach's Beginning Java with NetBeans",57.50m); Product p2 = (Product)p1.Clone(); //Clone returns object p2.Code = "BJWE"; //modifying Description p2.Description = "Murach's Beginning Java with Eclipse"; Console.WriteLine(p1.GetDisplayText("\n") + "\n"); Console.WriteLine(p2.GetDisplayText("\n") + "\n"); The output BJWN Murach's Beginning Java with NetBeans $57.50 BJWE Murach's Beginning Java with Eclipse
22
Shallow and Deep Clone Copy
Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements. Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.
23
Ex.: Shallow and Deep Clone Copy
shallow copy: A ob1 = new A(); ob1.a = 10; A ob2 = new A(); ob2 = ob1; ob1.a = 5; // ob2.a after this line = 5. Deep copy: ob2.a = ob1.a; ob1.a = 5; // ob2.a after this line = 10 copy-and-deep-copy-of-instance-using-C-Sharp/
24
Using an interface as a parameter
A CreateList method that uses an interface as a parameter public static List<object> CreateList(ICloneable obj,int count) { List<object> objects = new List<object>(); for (int i = 0; i < count; i++) object o = obj.Clone(); objects.Add(o); } return objects; A WriteToConsole method that uses an interface as a parameter public static void WriteToConsole(IDisplayable d) => Console.WriteLine(d.GetDisplayText("\n") + "\n");
25
Code that uses these methods
Product product = new Product("CS15","Murach's C# 2015",56.50m); List<object> products = CreateList(product, 3); foreach (Product p in products) { WriteToConsole(p); } The output that’s displayed CS15 Murach's C# 2015 $56.50
26
Using an interface as a parameter
You can declare a parameter that’s used by a method as an interface type. Then, you can pass any object that implements the interface to the parameter. Since the Product class implements both the ICloneable and IDisplayable interfaces, it can be passed as an argument to a method that accepts an object of the ICloneable or IDisplayable type.
27
Generics<T> You can use generics to define a type-safe collection that can accept elements of any type. To define a class for a generic collection, you code angle brackets after the name of the class, and you specify the type parameter within these brackets. Then, within the class, you can use the type parameter anywhere that a data type might be used. For example, you can use it as a return type or parameter type for a method. By convention, most programmers use the letter T as the type parameter for most classes. However, you can use any parameter name here.
28
Generics, CustomList ex.
Data Type (it can be any letter) public class CustomList<T> { private List<T> list = new List<T>(); // 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;
29
Generics, CustomList ex. cont.
// the ToString method public override string ToString() { string listString = ""; for (int i = 0; i < list.Count; i++) listString += list[i].ToString() + "\n"; } return listString;
30
Code that uses the CustomList<> class
// Test 1: using integer(s) in Custom List Console.WriteLine("List 1 - ints"); CustomList<int> list1 = new CustomList<int>(); int i1 = 11; int i2 = 7; list1.Add(i1); list1.Add(i2); Console.WriteLine(list1.ToString()); Output: List 1 - ints 11 7
31
Code that uses the CustomList<> class cont.
// Test 2: using Product(s) in Custom list Console.WriteLine("List 2 - Products"); CustomList<Product> list2 = new CustomList<Product>(); Product p1 = new Product("VB15", "Murach's Visual Basic 2015", 56.50m); Product p2 = new Product("CS15", "Murach's C# 2015", 56.50m); list2.Add(p1); list2.Add(p2); Console.Write(list2.ToString()); Output: List 2 - Products VB15 Murach's Visual Basic $56.50 CS15 Murach's C# $56.50
32
Generics Class Conclusion
The generic CustomList<> class works like the generic collection classes of the.NET Framework (chapter.) The resulting output of the two examples assumes that the Product class includes a ToString method that displays the product code, description, and price separated by tabs.
33
A common generic .NET interface
Compare with A common regular .NET interface Since the IComparable<> interface is a generic interface, you can use angle brackets after the IComparable<> interface to identify the type of the objects that are being compared. To implement the ICornparable<> interface, you must implement the CompareTo method. This method returns an int value that determines if the current element is less than, equal to, or greater than the element that’s passed as a parameter of the method.
34
Common .NET interfaces for generic collections
35
Common .NET interfaces for generic collections cont.
36
Common .NET Framework generic interfaces
The .NET Framework defines in any generic interfaces. These interfaces are particularly useful for working with classes that define generic collections. The ICollection<> interface inherits the [Enumerable<> interface, which means that any class that implements ICollection<> must also implement IEnumerable<>. Similarly, the IList<> and IDictionary<> interfaces inherit ICollection<> and IEnuInerable<>. The interfaces for working with generic collections are stored in the SystemCollections.Generic namespace.
37
A class that implements the IComparable<> 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); } Only Code matters, it is alphanumeric comparison
38
Code that uses the class
Product : IComparable<> Product p1 = new Product("VB15","Murach's Visual Basic 2015", 56.50m); Product p2 = new Product("CS15","Murach's C# 2015", 56.50m); int compareValue = p1.CompareTo(p2); if (compareValue > 0) Console.WriteLine("p1 is greater than p2"); else if (compareValue < 0) Console.WriteLine("p1 is less than p2"); else if (compareValue == 0) Console.WriteLine("p1 is equal to p2");
39
Values that can be returned by the CompareTo method
Value Meaning -1 The current element is less than the compare element. 0 The current element is equal to the compare element. 1 The current element is greater than the compare element. Ex.: Product 1 - Code VB15 Product 2 - Code CS15 Product1 > Product2
40
Ascii
41
Constrains To restrict the possible data types that a generic class can accept. For example, you may need to make sure that a generic class only accepts reference types, not value types. Or, you may need to make sure that a generic class inherits another class or implements an interface. To do that, you can code a constraint.
42
A class that uses constraints https://msdn. microsoft
CustomList<> class that uses the CompareTo method of an object to insert the object at a point in the list so the list is always sorted. public class CustomList<T> where T: class, IComparable<T> { private List<T> list = new List<T>(); // an Add method that keeps the list sorted public void Add(T item) if (list.Count == 0) //first item list.Add(item); } else for (int i = 0; i < list.Count; i++) T currentItem = list[i]; T nextItem = null; Classes that implement IComparable sorting
43
A class that uses constraints cont.
if (i < list.Count - 1) { nextItem = list[i + 1]; } int currentCompare = currentItem.CompareTo(item); if (nextItem == null) if (currentCompare >= 0) list.Insert(i, item); // insert before current item break; ...
44
Constrains Ex. It implements a sorted list.
To accomplish this task, this class restricts the types that can be accepted by the CustomList<> class to classes (which define reference types) that implement the IComparable<> interface. Since any T variable in this class must be a reference type, the Add method can assign a null value to a variable of type T. Then, later in the method, the code can check if that variable is still equal to a null value. This wouldn’t be possible without the constraint since you can’t assign a null value to a value type unless it’s defined as nullable. Similarly, since the T variable must implement the IComparable<> interface, the Add method can call the CompareTo method from that variable. Without the constraint, this wouldn’t be possible, as there would be no guarantee that the T variable would implement the IComparable<> interface.
45
How To code Constraints
To declare a constraint, you begin by coding the where keyword after the class declaration. Then, you code the generic type parameter (usually T) followed by a colon. Finally, you code a list of the constraints, separating each constraint with a comma. When you code these constraints, you must code them in a specific order. To start, if you want to constrain the generic type to a class or structure, you must code the class or struct keyword first. Similarly, if you want to constrain the generic type to a subclass of a particular class, you must code the name of that class first and you can’t use the class or struct keywords. After that, you can code a list of the interfaces that the type must implement. Finally, if you want to constrain the generic type to a class that has a default constructor, you can code the new() keyword at the end of the list. .
46
Keywords that can be used to define constraints
Keyword Description class The type argument must be a class. struct The type argument must be a structure other than one that defines a nullable type. new() The type argument must have a default constructor. You can’t use this keyword when the type argument must be a structure. 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()
47
Constraints Example First the implemented interfaces, then the generic type constraints separated by where: class SampleC<T> : IDisposable where T : IDisposable {↑ public void Dispose() { throw new NotImplementedException(); }
48
yield The foreach loop only works on generic collections that implement the IEnumerable<> interface. As a result, if you want to use the foreach loop on a generic collection that you’ve defined, you must implement the IEnumerable<> interface. For example, to be able to use a foreach loop on the generic collection defined by the CustomList<> class presented in this chapter, you must implement the IEnumerable<> interface for this class. To start, you can generate the method stubs for the IEnumerable<> interface. This includes stubs for the GetEnumerator method for both the regular enumerable interface and the generic IEnumerable<> interface. However, you only need to implement the GetEnumerator method for the generic IEnumerable<> interface. The easiest way to do that is to code a foreach loop that loops through each item in the list. Then, you can use the yield keyword together with the return keyword to return the current item to the enumerator object and to yield control. Ex.: With each execution of the foreach loop, the enumerator object (the list) returns a Product object and yields control to the foreach loop. This allows the foreach loop to call the ToString method of the Product object before yielding control back to the enumerator object. In short, this allows the two loops shown in this figure to be synchronized.
49
A class that implements IEnumerable<> Therefore you can use foreach (self-study)
public class CustomList<T> : IEnumerable<T> { private List<T> list = new List<T>(); //other members //generic public IEnumerator<T> GetEnumerator() foreach (T item in list) yield return item; } //regular, not implemented System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() throw new NotImplementedException(); }
50
yeld the-yield-keyword-used-for-in-c
51
Code that uses the class
Product p1=new Product("VB15","Murach's Visual Basic 2015",56.50m); Product p2 = new Product("CS15","Murach's C# 2015",56.50m); CustomList<Product> list = new CustomList<Product>(); list.Add(p1); list.Add(p2); foreach (Product p in list) { Console.WriteLine(p.ToString()); }
52
interface IGenericPersistable<T> { T Read(string id);
DB is coming! An interface named IGenericPersistable<> that uses generics Standard way for a business object to read itself from or write itself to a data such as a database. interface IGenericPersistable<T> { T Read(string id); bool Save(T obj); bool HasChanges get; set; }
53
A class that implements IGenericPersistable<>
class Customer : IGenericPersistable<Customer> { // other members public Customer Read(string id) throw new NotImplementedException(); } public bool Save(Customer obj)
54
A class that implements IGenericPersistable<>
public bool HasChanges { get throw new NotImplementedException(); } set
55
Exercise 15-1 Implement the ICloneable interface
Add code to a Customer class so it implements the ICloneable interface. Then, create a List<> that contains the requested number of clones and display the clones in a list box.
56
Project 3-5 Maintain student scores (Student class)
Develop an application that maintains a list of student scores using a Student class. This class will implement the ICloneable interface and the Clone method will implement a deep copy.
57
Project 3-6 Translate English to Pig Latin or Pig Greek
Create a form that converts a text entry to Pig Latin or Pig Greek. To do that, you’ll create an interface named ITranslator and two classes that provide the translations by implementing this interface.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.