Professional Documents
Culture Documents
Chapter - 6
Objectives
C# C# C# C# Interface basic concepts How to implement Interfaces in C#? Difference between Interfaces and Abstract base Classes Interface References: 'is', 'as', etc. Interfaces as Parameters Interfaces and Polymorphism Building Customized Types
IConvertible, IEnumerator, ICloneable, and IComparable, Interfaces
System.Collections Interface
ArrayList, Hashtable, Queue, SortedList, and Stack
2
Why Interfaces?
C# C# C# C#
They're great for putting together plug-n-play like architectures where components can be interchanged at will (example follows). Since all interchangeable components implement the same interface, they can be used without any extra programming. The interface forces each component to expose specific public members that will be used in a certain way.
3
Interface1 Interface2
Interface3
Contd..
C# C# C# C#
Syntax: interface interfaceName { member declarations; } Here, interface is the keyword Eg: interface show { void display(); } Interface can also declare properties & events Eg: interface Ex1 { int Aproperty { get; } // behavior as a read-only property event SomEevent changed; void Display(); } Accessibility of an interface can be controlled by modifiers public, private, internal & protected
6
Extending an Interface
C# C# C# C#
Interface extension an interface can be subinterfaced from other interfaces. New subinterface will inherit all the members of the superinterface Eg1: interface Addition { int Add(int x, int y); } interface Compute:Addition { int sub(int x, int y); } Eg2: interface I1 { . } interface I2 { . } interface I3: I1,I2 // multiple inheritance { . } Subinterfaces cannot define the method declared in the superinterfaces. An interface cannot extend the classes.
7
Implementing an Interface
C# C# C# C#
A class that implements an interface can explicitly implement a member of that interface. i.e., interfaces are used as supeclasses whose properties are inherited by classes. Interfaces may be implemented by classes and structures
public interface ISomeInterface { // Members.. } public class SomeClass : ISomeInterface { // implementation details of the interface } public class AnotherClass : BaseClass, ISomeInterface { // derives from BaseClass and implents the interface }
Example
C# C# C# C#
// program to illustrate implentation of multiple interface Using System; interface Addition { int Add(); } Interface Multiplication { int mul(); }
Public computation (int x, int y) // constructor { this.x = x; this.y = y; } Public int Add ( ) { return (x+y); } Public int Mul ( ) { return (x*y); } }
9
Example
C# C# C# C#
Class InterfaceTest { public static void Main() { computation com = new computation (10,20); Addition add = (Addition) com; // casting CW(Sum = + add.Add()); Multiplication mul = (Multiplication) com; // casting CW(Product = + mul.Mul()); } } Note: Cannot instantiate an interface directly. i.e., Addition add= new Addition(); //error Always create an instance of the implementing class & then cast the object to the interface type.
10
Contd..
C# C# C# C#
An abstract base class can use an interface in the base class list. Eg: interface A { void Method(); } abstract class B:A { .. public abstract void method(); } Note: the class B does not implement the interface method, it simply redeclare as a public abstract method. We can convert an interface into an abstract class interface A { void Print(); } abstract class B { abstract public void Print(); } Note: a class can inherit from B instead of implementing the interface A.
12
Shapes Hierarchy
C# C# C# C#
Shapes Class Draw( )
Ipointy Ipointy
Triangle Class
Circle Class
Hexagon Class
Draw()
Draw()
Draw()
13
C# C# C# C#
The most straightforward way to interact with functionality supplied by a given interface is to invoke the methods directly from the object level. Eg: public interface IPointy { byte Points { get; } } // Hexagon implements IPointy public class Hexagon : Shape, IPointy { .. public byte Points { get {return 6;} } } Class Example { static void Main (string [ ] args) { Hexagon hex = new Hexagon(); CW (Points : {0}, hex.Points); } } In specific case it works fine.
14
Contd
C# C# C# C#
Assume if an array contains 50 shapes compatible types, only some of which support IPointy. Obviously, if you attempt to invoke the Points property on a type that has not implementes IPointy, then you receive a compiler error This problem can be solved by 3 ways 1. Explicit Cast 2. As Keyword 3. Is Keyword 1. Use an explicit cast of specific interface to determine at runtime. For this use structured exception handling Eg: static void Main(string [ ] args) { Circle C = new Circle ( L); Ipointy pt1; try { pt1 = (iPointy) C; CW (pt2.Points); } Catch (InvalidCastException e) { CW (OOPS! Not a pointy..); } }
15
if (s[i] is IPointy)
Console.WriteLine("-> Points: {0}", ((IPoints)s[i]). Points);
else
Console.WriteLine("-> {0}\'s not points!", s[i].PetName);
}
17
Interfaces as Parameters
C# C# C# C#
Methods can take interfaces as parameters, as well as method return values Assume the following interface: public interface IDraw3D {
void Draw3D(); }
Now assume that the Circle subclass is revised to provide an additional implementation for IDraw3D public class Circle : Shape, IDraw3D { . public void Draw3D() { Console.WriteLine("Drawing a 3D Circle"); }
18
Interface as Parameter
C# C# C# C#
Public class Hexagon: Shape, Ipointy, IDraw3D { . public void Draw3D() { CW (Drawing Hexagon 3D); } } Public class ShapeApp { public static void DrawShape(IDraw3D objdraw) // parameter passing { Console.WriteLine("Drawing in 3D: compatible type"); if (objdraw is IDraw3D) return (IDraw3D)objdraw; // returning value else return null; }
19
Interface as Parameter
C# C# C# C#
Public static void Main() { Hexagon H=new Hexagon(); Circle C=new Circle(); IDraw3D Hobj=Drawshape(H); if (Hobj!=null) CW(It is a 3D Hexagon); else CW(Not 3D object); IPointy Cobj=Drawshape(C); If (Cobj!=null) CW(It is a 3D Circle); else CW(Not a 3D object); } }
20
Example
Explicit Interface Implementation
C# C# C# C#
Example
C# C# C# C#
// Explicit interface member implementation: float IDimensions.Length() { return lengthInches; } // Explicit interface member implementation: float IDimensions.Width() { return widthInches; }
23
Example
C# C# C# C#
public static void Main() { // Declare a class instance "myBox": Box myBox = new Box(30.0f, 20.0f); // Declare an interface instance "myDimensions": IDimensions myDimensions = (IDimensions) myBox; // Print out the dimensions of the box: /* The following commented lines would produce compilation errors because they try to access an explicitly implemented interface member from a class instance: */ //Console.WriteLine("Length: {0}", myBox.Length()); //Console.WriteLine("Width: {0}", myBox.Width()); /* Print out the dimensions of the box by calling the methods from an instance of the interface: */ Console.WriteLine("Length: {0}", myDimensions.Length()); Console.WriteLine("Width: {0}", myDimensions.Width()); } }
24
}
25
Super Si=new Super(); Ibase b1=(Ibase)Si; b1.Draw(); if (b1 is Iderv2) { Iderv2 d2 = (Iderv2) b1; d2.Render(); d2=Print(); }
} }
26
C# C# C# C#
Permissable to creat an interface that derives from multiple base interfaces Eg: public interface IYCar { void Drive(); } public interface IXCar IXCarderv1: Ibase { void Dive(); } public interface Iderv2: IYCar, IYCar { void Turbo(); } public class Car:IZCar { void Drive() { CW(Speeding up); } void Dive() { CW(Submerging); } void Turbo() { CW(Blast off); } } . Static Void Main(string[ ] args) { . Car C1=new Car(); C1.Drive(); C1.Turbo(); C1.Dive(); }
27
Assume, implement the ICar interface on a new class names MiniVan The first letter is underlined [ smart tag ] Click on smart tag provides selection to implement the interface explicitly or implicitly Built automatically stub code wrapped in a #region/#endregion
28
To access each member of IConvertible interface, explicitly request access to the interface Eg: bool myBool=true IConvertible Conv = (IConvertible) myBoll;
30
IConvertible defines a number of methods of the form ToXXXX(), it provides a way to convert from one type into another System types throw an InvalidCaseException if the conversion is semantically error. Eg: bool myBool = true; Iconvertible Conv =(IConvertible) myBool; try { Conv.ToSingle(); } catch (InvalidCastException e) { CW (e); }
31
IFormatProvider
C# C# C# C#
all ToXXXX() methods take a parameter of type IFormatProvider Objects that implement this interface are able to format their contents based on culture-specific information (eg. Float fomatted in various currencies) Definition: public interface IFormatProvider { Object GetFormat(Type formatType); } Custom type IFormatProvider implementation necessary System type - call from System.Globalization.CultureInfo
IConvertible Conv = (IConvertible) theInt; byte theByte = Conv.ToByte(CultureInfo.CurrentCulture); CW(Type code int converted to byte is :{0} , theByte.GetTypeCode()); CW(Value of converted int :{0}, theByte);
32
IConvertible.GetTypeCode()
C# C# C# C#
Available to any class or structure implemeting IConvertible Allows to programmatically discover a value that represents the typecode of the type, which is represented by the following enumeration: public enum TypeCode { Boolean, Byte, Char, DateTime, DBNull, Decimal, Double, Empty, Int16, Int32, Int64, object, SByte, Single, String, UInt16, UInt32, UInt64 }
33
Contd
C# C# C# C#
When tried for execution gives error the Cars class does not implement a method GetEnumerator() GetEnumerator defined by IEnumberable interface IEnumerable informs- objects subitems can be enumerated. Formal definition of IEnumerable is: public interface IEnumerable { IEnumerator GetEnumerator(); }
35
Contd
C# C# C# C# GetEnumerator() returns a referance to another interface names System.Collections.IEnumerator. IEnumerator interface allow to traverse the internal objects contained by the IEnumerable compatible type. public interface IEnumerator { bool MoveNext(); // Advance the internal position of the cursor object Current{ get; } // Get the current item void Reset(); // Reset the cursor before the first member } So update the program as follows.
36
Contd
C# C# C# C#
using System.Collections; . public Class Cars:IEnumerable { private car[ ] CarArray; public Cars() { CarArray = new Car[4]; CarArray[0] = new Car(Rashu, 30); CarArray[1] = new Car(Charan, 55); CarArray[2] = new Car(Zohra, 20); CarArray[3] = new Car(Hema, 30); } Public IEnumerator GetEnumerator() { //return the array objects IEnumerator return CarArray.GetEnumerator(); } } Now safely use the type within the c# foreach construct.
37
Since the System.Array type already implements IEnumerator, you need not add this interface to Cars class
public class Cars : IEnumerable //, IEnumerator { private car[ ] carArray; .. public IEnumerator GetEnumerator() { return carArray.GetEnumerator( ); } .. }
38
Shapes Hierarchy
C# C# C# C#
Shapes Class Draw( )
Triangle Class
Circle Class
Hexagon Class
Draw()
Draw()
Draw()
39
Circle SubClass
C# C# C# C#
} }
41
Hexagon SubClass
C# C# C# C#
public class Hexagon : Shape, IPoints { public Hexagon(){} public Hexagon(string name): base(name){} public override void Draw() { Console.WriteLine("Drawing " + PetName + "Hexagon"); } // Implements IPoints public byte Points { get{ return 6; } } }
42
Example-1
C# C# C# C# public static int Main(string[] args) {
Circle c = new Circle("Red"); c.Draw(); Hexagon h = new Hexagon("Blue"); h.Draw(); //IPoints MyShape = (IPoints) h; //Console.WriteLine(MyShape.GetNumberOfPoints()); Console.WriteLine(h.GetNumberOfPoints()); return 0;
ERROR
43
Example - 2
C# C# C# C#
44
Example 2
C# C# C# C#
class Person : IAge { private string firstName; private string lastname = "......"; private int yearBorn; public int Age { get { return DateTime.Now.Year - yearBorn; } set { yearBorn = value; } } public string Name { get { return firstName + " " + lastname; } set { firstName = value; } }
45
Example 2
C# C# C# C# static void Main(string[] args) { Person p = new Person(); p.Name = "Geetha"; p.Age = 1986; Console.WriteLine("Name = {0}",p.Name); Console.WriteLine("Age = {0}",p.Age); IAge[ ] AgeArray = new IAge[2]; // ..
}
}
46
Part - II
C# C# C# C#
IConvertible
Dynamic conversion of data types
ICloneable
To provide a standard way to create copies of existing objects
IDictionary
To map keys to values Associative arrays
IList
Access to individual items, removal, and insertion at any point
47
IConvertible Interface
C# C# C# C# Allows dynamic conversion of data types through interface based programming technique What are the methods defined in IConvertible Interface?
public interface IConvertible { bool ToBoolean(IFormatProvider provider); char ToChar(IFormatProvider provider); UInt64 ToUInt64(IFormatProvider provider); }
48
Accessing Members
C# C# C# C# To gain access to each member of IConvertible interface, you must explicitly request access to the interface
// uses explicit interface implementation bool myBoll = true; IConvertible i = (IConvertible) myBool;
Type Conversions
C# C# C# C#
Integer using System.Globalization; int theInt = 65; Console.WriteLine("Type code of int is: ",theInt.GetTypeCode()); Int to Char using Type Casting char theChar = (char)theInt; Console.WriteLine("Type code int converted to char is: {0}", theChar.GetTypeCode()); Console.WriteLine("Value of converted char: {0}", theChar); Int to Byte using IConvertible IConvertible itfConvert = (IConvertible)theInt; byte theByte = itfConvert.ToByte(CultureInfo.CurrentCulture); Console.WriteLine("Type code int converted to byte is: {0}", theByte.GetTypeCode()); Console.WriteLine("Value of converted int: {0}", theByte);
50
Type Conversion
C# C# C# C# Convert a System.String into a System.Boolean using System.Convert
string theString = "true"; bool theBool = Convert.ToBoolean(theString); Console.WriteLine("Type code string converted to bool is: {0}", theBool.GetTypeCode()); Console.WriteLine("Value of converted string: {0}", theBool);
Objects that implement this interface are able to format their contents based on culture specific information
52
There are several classes which implement IEnumerable and IEnumerator interfaces. For example, Array, ArrayList, Stack, Queue, etc. are the classes that implement IEnumerable interface
53
C# C# C# C#
public class CarDriver { public static void Main() { Cars carLot = new Cars(); Console.WriteLine("Here are the cars in your lot"); foreach (Car c in carLot) { Console.WriteLine("-> Name: {0}", c.PetName); Console.WriteLine("-> Max speed: {0}", c.MaxSpeed); Console.WriteLine(); } } }
This code issues an error for not implementing the GetEnumerator() method
55
Implementing GetEnumerator()
To get around the problem of compilation error, we must use public class Cars : IEnumerable { .. // GetEnumerator() returns IEnumerator public IEnumerator GetEnumerator() { // ??????? } .. } IEnumerable.GetEnumerator() returns an object implementing IEnumerator public interface IEnumerator { bool MoveNext(); object Current { get; } void Reset(); }
56
C# C# C# C#
57
Implementation of MoveNext().
C# C# C# C#
public bool MoveNext() { if(pos < carArray.Length) { pos++; return true; } else return false; } public void Reset() { pos = 0; } public object Current { get { return carArray[pos]; } }
58
Advantages
C# C# C# C#
User types can be iterated through 'foreach' loop When the IEnumerator members are explicitly implemented, we provide an alternate method of accessing the objects in the container
59
Since the System.Array type already implements IEnumerator, you need not add this interface to Cars class
public class Cars : IEnumerable //, IEnumerator { private car[ ] carArray; .. public IEnumerator GetEnumerator() { return carArray.GetEnumerator( ); } .. }
With this, there is no need to implement manually MoveNext(), Reset(), etc. (refer ObjEnum folder)
60
Recall System.Object has a member MemberwiseClone() which does shallow copy Object users can call this method with an instance for cloning process
61
Example
C# C# C# C#
public class Point { public int x, y; public Point(){} public Point(int x, int y) { this.x = x; this.y = y; } public override string ToString() { return "X: " + x + " Y: " + y; } }
The following piece of code makes two references pointing to the same copy of the objects in heap
Point p1 = new Point(50, 50); Point p2 = p1; p2.x = 0;
ICloneable Interface
C# C# C# C# To avoid the shallow copy problem we must implement the ICloneable interface
public interface ICloneable { object Clone(); }
This means the Clone() method need to be redefined to suit the customer type. This ensures deep copy semantics
public class Point : ICloneable { .. public object Clone() { return new Point(this.x, this.y); } . }
63
What happens if the Point type contains references to other internal reference types? [it becomes a shallow copy] If we wish to support a true deep copy, we need to create a new instance of any reference type variables during the cloning process.
64
65
int IComparable.CompareTo(object o) { Student temp = (Student) o; if(this.USN > temp.USN) return 1; if(this.USN < temp.USN) return -1; else return 0; }
}
66
Recall, the IComparable interface was implemented using the type name (Student). But, IComparer is implemented using some helper classes, one for each sort order (USN, Name, etc).
68
69
C# C# C# C#
System.Sort has a number of overloaded methods. One of them is to take an object implementing IComparer static void Main(string[] args) { Student[] cseStd = new Student[3]; cseStd[0] = new Student(111,"Scott"); cseStd[1] = new Student(100,"Allen"); cseStd[2] = new Student(45,"John"); try { Array.Sort(cseStd, new SortName()); } catch(Exception e) { Console.WriteLine(e.StackTrace); } Console.WriteLine("Array after Sorting by Name:"); foreach(Student s in cseStd) Console.WriteLine(s.USN + " " + s.Name); } } 70
The helper classes may be static public class car : IComparable { public static IComparer class SortName { . } } // Calling program Array.Sort(cseStd, Student.SortName());
71
IDictionaryEnumerat or
IEnumerable IEnumerator IHashCodeProvider
IKeyComparer
Combines the functionality of IComparer & IHashcodePRovider to allow object to be compared in a hash-code-compatible manner
Provides behavior to Add, Remove, & Index items in a list 72 of objects.
IList
Contd
C# C# C# C#
Many of these interfaces are related by an interface hierarchy & some are stand alone entities.
IDictionary
interface
IEnumerable
interface
IList
interface
ICollection
interface
IEnumerator
interface
IDictionary IEnumerator
interface
73
76
System.Collections Namespace
C# C# C# C# Sytem.Collections has many classes
ArrayList
Hashtable Queue SortedList
collection of objects IDictionary, ICollection, identified by keys IEnumerable, & ICloneable FIFO ICollection, IEnumerable, & ICloneable
Same as Dictionary, IDictionary, ICollection, but accessed by IEnumerable, & ICloneable index LIFO ICollection and IEnumerable
Stack
78
ArrayList Basics
C# C# C# C#
The ArrayList is not guaranteed to be sorted. You must sort the ArrayList prior to performing operations (such as BinarySearch) that require the ArrayList to be sorted. The capacity of a ArrayList is the number of elements the ArrayList can hold. The default initial capacity for an ArrayList is 0. As elements are added to a ArrayList, the capacity is automatically increased as required through reallocation. The capacity can be decreased by calling TrimToSize or by setting the Capacity property explicitly. Elements in this collection can be accessed using an integer index. Indexes in this collection are zero-based. ArrayList accepts a null reference as a valid value and allows duplicate elements.
79
Example
C# C# C# C#
myAL Count: 3 using System; using System.Collections; Capacity: 16 public class SamplesArrayList { Values: Hello World ! public static void Main() { // Creates and initializes a new ArrayList. ArrayList myAL = new ArrayList(); myAL.Add("Hello"); myAL.Add("World"); myAL.Add("!"); // Displays the properties and values of the ArrayList. Console.Write( "myAL" ); Console.WriteLine( " Count: {0}", myAL.Count ); Console.WriteLine( " Capacity: {0}", myAL.Capacity ); Console.Write( " Values:" ); PrintValues( myAL ); } public static void PrintValues( IEnumerable myList ) { foreach ( Object obj in myList ) Console.Write( " {0}", obj ); Console.WriteLine(); }
80
System.ArrayList
C# C# C# C#
81
System.ArrayList.
C# C# C# C#
System.Collections.Queue
C# C# C# C#
Dequeue() Delete and return first object from the Queue Enqueue() Insert an object into the Queue Peek() Return the first object without deleting Console.WriteLine("\n***** Queue Demo *****"); // Now make a Q with three items Queue carWashQ = new Queue(); carWashQ.Enqueue(new Car("FirstCar", 0, 0)); carWashQ.Enqueue(new Car("SecondCar", 0, 0)); carWashQ.Enqueue(new Car("ThirdCar", 0, 0));
System.Collections.Queue
C# C# C# C#
// Remove each item from Q WashCar((Car)carWashQ.Dequeue()); WashCar((Car)carWashQ.Dequeue()); WashCar((Car)carWashQ.Dequeue()); // Try to de-Q again? try { WashCar((Car)carWashQ.Dequeue()); } catch(Exception e) { Console.WriteLine("Error!! {0}", e.Message);}
84
System.Collections.Stack
C# C# C# C#
Stack stringStack = new Stack(); stringStack.Push("One"); stringStack.Push("Two"); stringStack.Push("Three"); // Now look at the top item. Console.WriteLine("Top item is: {0}", stringStack.Peek()); Console.WriteLine("Popped off {0}", stringStack.Pop()); Console.WriteLine("Top item is: {0}", stringStack.Peek()); Console.WriteLine("Popped off {0}", stringStack.Pop()); Console.WriteLine("Top item is: {0}", stringStack.Peek()); Console.WriteLine("Popped off {0}", stringStack.Pop()); try { Console.WriteLine("Top item is: {0}", stringStack.Peek()); Console.WriteLine("Popped off {0}", stringStack.Pop()); } catch(Exception e) { Console.WriteLine("Error!! {0}\n", e.Message);}
85
C# C# C# C#
End of Chapter 6
86