Professional Documents
Culture Documents
UNIT VI
Interfaces and Collections
Defining Interfaces Using C#
An interface is nothing more than a named collection of semantically related abstract
members.
An interface expresses a behavior that a given class or structure may choose to implement.
Unlike other .NET types, interfaces never specify a base class and contain members that do not
take an access modifier.
To begin, create a brand-new Console Application named user_interface.
Using the Project ->Add Existing Item menu option, insert an interface to the project.
An interface is defined using the C# interface keyword.
Unlike other .NET types, interfaces never specify a base class (not even System.Object) and
their members never specify an access modifier (as all interface members are implicitly public
and abstract).
To get the ball rolling, here is a custom interface defined in C#:
public interface IPoints
{
int points();
}
Notice that when we define interface members, we do not define an implementation scope for
the member in question.
.NET interface types are also able to define any number of property prototypes.
Implementing an Interface
When a class (or structure) chooses to extend its functionality by supporting interface types, it
does so using a comma-delimited list in the type definition.
Be aware that the direct base class must be the first item listed after the colon operator.
namespaceuser_interface
{
publicclassshapes
{
protectedvoiddisplay()
{
Console.WriteLine("Allareshapes");
}
}
publicclasssquare:shapes,IPoints
{
publicintpoints()
{
return4;
}
publicvoidprint()
{
base.display();
Console.WriteLine("Square");
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
circlec1=newcircle();
c1.print();
Console.Read();
}
}
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
This approach works fine in this particular case, given that we are well aware that the square
type has implemented the interface in question and therefore has a Points property.
Obtaining Interface References: Explicit Casting
Other times, however, we may not be able to determine which interfaces are supported by a
given type.
If we attempt to invoke the Points property on a type that has not implemented IPoints, we
receive an error.
Next question: how can we dynamically determine the set of interfaces supported by a type?
One way to determine at runtime whether a type supports a specific interface is to make use of
an explicit cast.
If the type does not support the requested interface, we receive an InvalidCastException.
To handle this possibility gracefully, make use of structured exception handling, for example:
try
{
circlec1=newcircle();
c1.print();
/*IPointsip=(IPoints)c1;
Console.WriteLine(ip.points());*/
Console.WriteLine(((IPoints)c1).points());
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
circlec1=newcircle();
c1.print();
IPointsip=c1asIPoints;
if(ip!=null)
Console.WriteLine(ip.points());
else
Console.WriteLine("IPointsinterfacenotimplemented");
}
circlec1=newcircle();
c1.print();
if(c1isIPoints)
Console.WriteLine(c1.points());
else
Console.WriteLine("IPointsinterfaceisnotused");
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
Interfaces as Parameters
Given that interfaces are valid .NET types, we may construct methods that take interfaces as
Parameters.
namespaceinterface_param
{
interfaceIPrint
{
voidprint();
}
publicclasssquare:IPrint
{
publicvoidprint()
{
Console.WriteLine("Square");
}
}
publicclasstriangle:IPrint
{
publicvoidprint()
{
Console.WriteLine("Triangle");
}
}
classProgram
{
publicstaticvoiddisplay(IPrintip)
{
Console.WriteLine("PrintingIPrint");
ip.print();
}
staticvoidMain(string[]args)
{
squares1=newsquare();
if(s1isIPrint)
display((IPrint)s1);
Console.Read();
}
}
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
interfacelibrary
{
voiddisp_lib();
}
interfacereference:library
{
voiddisp_ref();
}
interfacejournal:reference
{
voiddisp_jour();
}
publicclassbooks:journal
{
publicvoiddisp_lib()
{
Console.WriteLine("CollegeLibrary");
}
publicvoiddisp_ref()
{
Console.WriteLine("ReferenceSectioninLibrary");
}
publicvoiddisp_jour()
{
Console.WriteLine("JournalSectioninReference");
}
}
classProgram
{
staticvoidMain(string[]args)
{
booksb1=newbooks();
b1.disp_lib();
b1.disp_ref();
b1.disp_jour();
Console.Read();
}
}
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
interfaceIBasicCar
{
voidDrive();
}
interfaceIUnderWaterCar
{
voidDive();
}
interfaceICar007:IBasicCar,IUnderWaterCar
{
voidSuper();
}
publicclassBond:ICar007
{
voidIBasicCar.Drive()
{
Console.WriteLine("Speedingup...");
}
voidIUnderWaterCar.Dive()
{
Console.WriteLine("Submering...");
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
IFormatProvider
All the ToXXX() methods take a parameter of type IFormatProvider.
Objects that implement this interface are able to format their contents based on culture-specific
information.
public interface IFormatProvider
{
object GetFormat(Type formattype);
}
IConvertible.GetTypeCode
In addition to ToXXXX() members, IConvertible defines a member named GetTypeCode().
This method allows to discover the value that represents the type code of type.
The System.Convert type
The System namespace defines a type named Convert, which echoes the functionality of the
IConvertible interface.
The same set of members is defined in System.Convert.
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
publicclassPoint
{
//Publicforeasyaccess.
publicintx,y;
publicPoint(intx,inty){this.x=x;this.y=y;}
publicPoint(){}
//OverrideObject.ToString().
publicoverridestringToString()
{returnstring.Format("X={0};Y={1}",x,y);}
}
classProgram
{
staticvoidMain(string[]args)
{
Console.WriteLine("*****FunwithObjectCloning*****\n");
//Tworeferencestosameobject!
Pointp1=newPoint(50,50);
Pointp2=p1;
p2.x=0;
Console.WriteLine(p1);
Console.WriteLine(p2);
Console.ReadLine();
}
}
}
publicclassPoint:ICloneable
{
publicintx,y;
publicPoint(){}
publicPoint(intx,inty){this.x=x;this.y=y;}
//Returnacopyofthecurrentobject.
publicobjectClone()
{returnnewPoint(this.x,this.y);}
publicoverridestringToString()
{returnstring.Format("X={0};Y={1}",x,y);}
}
classProgram
{
staticvoidMain(string[]args)
{
Console.WriteLine("*****FunwithObjectCloning*****\n");
//NoticeClone()returnsagenericobjecttype.
//Youmustperformanexplicitcasttoobtainthederivedtype.
Pointp3=newPoint(100,100);
Pointp4=(Point)p3.Clone();
//Changep4.x(whichwillnotchangep3.x).
p4.x=0;
//Printeachobject.
Console.WriteLine(p3);
Console.WriteLine(p4);
Console.ReadLine();
}
}
}
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
IComparable
The role of IComparable is to provide a method of comparing two objects of a particular type.
This is necessary if you want to provide any ordering capability for your object. Think of
IComparable as providing a default sort order for your objects. For example, if you have an
array of objects of your type, and you call the
Sort method on that array, IComparable
provides the comparison of objects during the sort. When you implement the IComparable
interface, you must implement the CompareTo method.
The System.IComparable interface specifies a behavior that allows an object to be sorted based
on some specified key.
Here is the formal definition:
// This interface allows an object to specify its relationship between other like objects.
public interface IComparable
{
int CompareTo(object o);
}
When we build custom types, we can implement IComparable to allow arrays of our types to
be sorted.
When we flesh out the details of CompareTo(), it will be up to the user to decide what the
baseline of the ordering operation will be.
For the Car type, the internal carID seems to be the logical candidate.
The logic behind CompareTo() is to test the incoming type against the current instance based
on a specific point of data.
The return value of CompareTo() is used to discover whether this type is less than, greater
than, or equal to.
Table 9-1. CompareTo() Return Values
CompareTo() Return
Value
Any number less than zero
Zero
Any number greater than zero
Meaning in Life
This instance comes before the specified object in the sort order.
This instance is equal to the specified object.
This instance comes after the specified object in the sort order.
namespacecompare
{
publicclassCar:IComparable
{
privateintcarID;
privatestringpetName;
publicintID
{
get{returncarID;}
set{carID=value;}
}
publicCar(stringname,intid)
{
petName=name;
carID=id;
}
publicvoidprint()
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE
IComparer
The role of IComparer is to provide additional comparison mechanisms. For example, you
may want to provide ordering of your class on several fields or properties, ascending and
descending order on the same field, or both.
IComparer,
Mrs. R.Ushasree
Asst Prof of M. C. A.,
TOCE