Interface question

T

tshad

I am trying to understand Interfaces and why I would use them.

I have an example from a book that is explaining it.

I just can't seem to see why I would use it.

In my example, it has 2 interfaces: IDisplayable and IComparable
(Predefined).

In the Students class part, he is moving the students array to an
IComparable Object array and then sorting it.

// utilize the IComparable interface to sort the
// array
IComparable[] comparableObjects = (IComparable[])students;
Array.Sort(comparableObjects);

And then it moves the student array into the new IDisplayable interface:

// now the IDisplayable interface to display the results
IDisplayable[] displayableObjects = (IDisplayable[])students;
DisplayArray(displayableObjects);

And as is shown in the Birds section, I just do:

Array.Sort(students);
DisplayArray(students);

I get the same results.

And if I have to implement all the functions described in the Interface,
what am I really inheriting?

Why not just use an abstract class to do this?

Just a little confused.

Thanks,

Tom
 
N

Nicholas Paldino [.NET/C# MVP]

Tom,

You aren't inheriting anything. Interfaces provide the contract, while
an abstract class provides a contract (through abstract/virtual methods) and
possibly an implementation.

Interfaces are better used in situations where there isn't a clear
default implementation (in this case, the IComparable interface). It is
also better to use interfaces in general because you might not have the
opportunity to define the base class on your class (due to the fact that you
can only inherit from one base class).
 
S

sloan

Here is a little "Hopefully, the light will go off" example.
http://sholliday.spaces.live.com/Blog/cns!A68482B9628A842A!126.entry

This is not directly related to your example below.

But the premise is the same.

I can make my routines more flexible, by having interfaces as the
parameters. Thus I don't hard code to any one concrete class
implementation.


//> Why not just use an abstract class to do this?//

Maybe you can. However, you can only inherit from ONE abstract class (no
multiple class inheritance).
You can implement N number of interfaces. (zero, one, two, ten,
nine-hundred).


If you are new to OO and probably Design Patterns, I suggest:
http://www.dofactory.com/Patterns/Patterns.aspx
and the Head First Design Patterns book.


You may need to post a working sample, because you're asking the group to
evaluate...your evaluation... of another person's code.
So its hard to see what he is doing.
 
T

teel

I am trying to understand Interfaces and why I would use them.

I once used interfaces in C# and understood them - I've seen a huge
power they had, but now I forgot what power it was :)
I remember the situation when I used them: just had an object of class
(let's say Ford) derived some levels deep but operated it virtually,
like Vehicle. Ford implemented some interface (e.g ICrappyModel :))))
so I actually was assured it implements specific methods or properties
which the more generic class (lets say nor Car neither Vehicle)
didn't. And I had a Vehicle veh variable and wanted to know whether I
can run a Ford-specific method, so I used:
if (veh is ICrappyModel) { (ICrappyModel).GoToScrap() }

I hope this helped :)

Best regards,
teel
 
J

James Jardine

tshad said:
I am trying to understand Interfaces and why I would use them.

I have an example from a book that is explaining it.

I just can't seem to see why I would use it.

In my example, it has 2 interfaces: IDisplayable and IComparable
(Predefined).

In the Students class part, he is moving the students array to an
IComparable Object array and then sorting it.

// utilize the IComparable interface to sort the
// array
IComparable[] comparableObjects = (IComparable[])students;
Array.Sort(comparableObjects);

And then it moves the student array into the new IDisplayable interface:

// now the IDisplayable interface to display the results
IDisplayable[] displayableObjects = (IDisplayable[])students;
DisplayArray(displayableObjects);

And as is shown in the Birds section, I just do:

Array.Sort(students);
DisplayArray(students);

I get the same results.

And if I have to implement all the functions described in the Interface,
what am I really inheriting?

Why not just use an abstract class to do this?

Just a little confused.

Thanks,

Tom
I think a lot of people have difficulty understanding Interfaces and
Abstract classes at first. I find that I rarely use an abstract class
and more often use Interfaces because of some of the constraints
regarding inheritance vs. implements. A good example of the use of an
interface is for an application that allows add-ins or plug-ins to it.
Outlook for example uses an Interface that all Add-ins must implement.
This allows Outlook to talk to each add-in but allow each add-in to
function its own way.
 
S

sloan

I would look at the Observer pattern.

Its a very simple , yet powerful example of how (by using interfaces) , you
can get objects to be notified of an event....without hardcoding.

http://www.dofactory.com/Patterns/PatternObserver.aspx

I think the dofactory examples (free ones) actually use an Abstract class.

However, an interface could also be used.

Again, its the "inherit one abstract class, and THAT"S IT" argument, over N
number of interfaces.




sloan said:
Here is a little "Hopefully, the light will go off" example.
http://sholliday.spaces.live.com/Blog/cns!A68482B9628A842A!126.entry

This is not directly related to your example below.

But the premise is the same.

I can make my routines more flexible, by having interfaces as the
parameters. Thus I don't hard code to any one concrete class
implementation.


//> Why not just use an abstract class to do this?//

Maybe you can. However, you can only inherit from ONE abstract class (no
multiple class inheritance).
You can implement N number of interfaces. (zero, one, two, ten,
nine-hundred).


If you are new to OO and probably Design Patterns, I suggest:
http://www.dofactory.com/Patterns/Patterns.aspx
and the Head First Design Patterns book.


You may need to post a working sample, because you're asking the group to
evaluate...your evaluation... of another person's code.
So its hard to see what he is doing.




tshad said:
I am trying to understand Interfaces and why I would use them.

I have an example from a book that is explaining it.

I just can't seem to see why I would use it.

In my example, it has 2 interfaces: IDisplayable and IComparable
(Predefined).

In the Students class part, he is moving the students array to an
IComparable Object array and then sorting it.

// utilize the IComparable interface to sort the
// array
IComparable[] comparableObjects = (IComparable[])students;
Array.Sort(comparableObjects);

And then it moves the student array into the new IDisplayable interface:

// now the IDisplayable interface to display the results
IDisplayable[] displayableObjects = (IDisplayable[])students;
DisplayArray(displayableObjects);

And as is shown in the Birds section, I just do:

Array.Sort(students);
DisplayArray(students);

I get the same results.

And if I have to implement all the functions described in the Interface,
what am I really inheriting?

Why not just use an abstract class to do this?

Just a little confused.

Thanks,

Tom
 
T

tshad

sloan said:
Here is a little "Hopefully, the light will go off" example.
http://sholliday.spaces.live.com/Blog/cns!A68482B9628A842A!126.entry

This is not directly related to your example below.

It is and helps.

I am curious about something in the program.

The interface it uses is IAnimal. So everything that inherits from IAnimal
must have a MakeSound Method.

public interface IAnimal
{
string MakeSound();
}

The different animal classes all derive from IAnimal and do have the
MakeSound method.

public class Cat : IAnimal
{
public string MakeSound()
{
return "Meow";
}
public override string ToString()
{
return "*Cat*";
}
}

One question is: Why don't they have ToString() as part of the Interface?

Is the reason for having the IAnimal interface just so they can force a
method?

Also, what is the difference between the animal classes that inherited from
IAnimal:

public class Cat : IAnimal

and this class that IS IAnimal?

public class AnimalFactory
{
public static IAnimal GetAnimal(string key)
{
switch (key.ToUpper())
{
case "B":
return new Bird();
case "C":
return new Cat();
case "D":
return new Dog();
default:
throw new ArgumentException("The AnimalFactory was given a
Bad Key");
}
}
}

This was confusing to me.

In the case of the animals they were not an IAnimal class but a bird or cat
class and had to have MakeSound() method. But the above GetAnimal() method
IS an IAnimal Class and doesn't have the MakeSound() method.
But the premise is the same.

I can make my routines more flexible, by having interfaces as the
parameters. Thus I don't hard code to any one concrete class
implementation.


//> Why not just use an abstract class to do this?//

Maybe you can. However, you can only inherit from ONE abstract class (no
multiple class inheritance).
You can implement N number of interfaces. (zero, one, two, ten,
nine-hundred).


If you are new to OO and probably Design Patterns, I suggest:
http://www.dofactory.com/Patterns/Patterns.aspx
and the Head First Design Patterns book.

I will look at this later today.
You may need to post a working sample, because you're asking the group to
evaluate...your evaluation... of another person's code.
So its hard to see what he is doing.

My mistake.

I was planning on pasting it in but must have forgot to paste it in.

***********************************************************
// IDisplayable - an object that can convert itself into
// a displayable string format
interface IDisplayable
{
// GetString - return a string representation of yourself
string GetString();
}

void Page_Load()
{
// Sort students by grade...
Console.WriteLine("Sorting the list of students");

// get an unsorted array of students
Student[] students = Student.CreateStudentList();

// utilize the IComparable interface to sort the
// array
IComparable[] comparableObjects = (IComparable[])students;
Array.Sort(comparableObjects);

// now the IDisplayable interface to display the results
IDisplayable[] displayableObjects = (IDisplayable[])students;
DisplayArray(displayableObjects);


// Now sort an array of birds by name using
// the same routines even though the class Bird and
// Student have no common base class
Console.WriteLine("\nSorting the list of birds");
Bird[] birds = Bird.CreateBirdList();

// notice that it's not really necessary to cast the
// objects explicitly...
Array.Sort(birds);
DisplayArray(birds);

// wait for user to acknowledge the results
Console.WriteLine("Press Enter to terminate...");
Console.Read();
}

// DisplayArray - display an array of objects that
// implement the IDisplayable interface
public static void DisplayArray
(IDisplayable[] displayables)
{
int length = displayables.Length;
for(int index = 0; index < length; index++)
{
IDisplayable displayable = displayables[index];
Console.WriteLine("{0}", displayable.GetString());
}
}
// ----------- Students - sort students by grade -------
// Student - description of a student with name and grade
class Student : IComparable, IDisplayable
{
private string sName;
private double dGrade = 0.0;


// Constructor - initialize a new student object
public Student(string sName, double dGrade)
{
// save off the object's data
this.sName = sName;
this.dGrade = dGrade;
}


// CreateStudentList - to save space, just create
// a fixed list of students
static string[] sNames =
{"Homer", "Marge", "Bart", "Lisa", "Maggie"};
static double[] dGrades =
{0, 85, 50, 100, 30};
public static Student[] CreateStudentList()
{
Student[] sArray = new Student[sNames.Length];
for (int i = 0; i < sNames.Length; i++)
{
sArray = new Student(sNames, dGrades);
}
return sArray;
}


// access read-only methods
public string Name
{
get
{
return sName;
}
}
public double Grade
{
get
{
return dGrade;
}
}

// implement the IComparable interface:
// CompareTo - compare another object (in this case,
// Student objects) and decides that
// one comes after the other in the
// sorted array
public int CompareTo(object rightObject)
{
// compare the current Student (let's call her
// 'left') against the other student (we'll call
// her 'right') - generate an error if both
// left and right are not Student objects
Student leftStudent = this;
if (!(rightObject is Student))
{
Console.WriteLine
("Compare method passed a nonStudent");
return 0;
}
Student rightStudent = (Student)rightObject;

// now generate a -1, 0 or 1 based upon the
// sort criteria (the student's grade)
// (the Double class has a CompareTo() method
// we could have used instead)
if (rightStudent.Grade < leftStudent.Grade)
{
return -1;
}
if (rightStudent.Grade > leftStudent.Grade)
{
return 1;
}
return 0;
}

// implement the IDisplayable interface:
// GetString - return a representation of the student
public string GetString()
{
string sPadName = Name.PadRight(9);
string s = String.Format("{0}:{1:N0}",
sPadName, Grade);
return s;
}
}

// -----------Birds - sort birds by their names--------
// Bird - just an array of bird names
class Bird : IComparable, IDisplayable
{
private string sName;

// Constructor - initialize a new student object
public Bird(string sName)
{
this.sName = sName;
}

// CreateBirdList - return a list of birds to the caller;
// use a canned list to save time
static string[] sBirdNames =
{ "Oriole", "Hawk", "Robin", "Cardinal",
"Bluejay", "Finch", "Sparrow"};
public static Bird[] CreateBirdList()
{
Bird[] birds = new Bird[sBirdNames.Length];
for(int i = 0; i < birds.Length; i++)
{
birds = new Bird(sBirdNames);
}
return birds;
}

// access read-only methods
public string Name
{
get
{
return sName;
}
}

// implement the IComparable interface:
// CompareTo - compare the birds by name; use the
// built in String class compare method
public int CompareTo(object rightObject)
{
// we'll compare the "current" bird to the
// "right hand object" bird
Bird leftBird = this;
Bird rightBird = (Bird)rightObject;

return String.Compare(leftBird.Name, rightBird.Name);
}

// implement the IDisplayable interface:
// GetString - returns the name of the bird
public string GetString()
{
return Name;
}
}
***********************************************************

Thanks,

Tom
tshad said:
I am trying to understand Interfaces and why I would use them.

I have an example from a book that is explaining it.

I just can't seem to see why I would use it.

In my example, it has 2 interfaces: IDisplayable and IComparable
(Predefined).

In the Students class part, he is moving the students array to an
IComparable Object array and then sorting it.

// utilize the IComparable interface to sort the
// array
IComparable[] comparableObjects = (IComparable[])students;
Array.Sort(comparableObjects);

And then it moves the student array into the new IDisplayable interface:

// now the IDisplayable interface to display the results
IDisplayable[] displayableObjects = (IDisplayable[])students;
DisplayArray(displayableObjects);

And as is shown in the Birds section, I just do:

Array.Sort(students);
DisplayArray(students);

I get the same results.

And if I have to implement all the functions described in the Interface,
what am I really inheriting?

Why not just use an abstract class to do this?

Just a little confused.

Thanks,

Tom
 
J

Jeff Louie

tshad... The GetAnimal simply _returns_ an object that implements
IAnimal.
The enclosing AnimalFactory class itself does not implement IAnimal. So
the
AnimalFactory class itself does not need to have a MakeSound() method.
The key
is that as long as an object implements IAnimal you can invoke
GetSound() on
the object without knowing if it the actual object is a cat, dog or
whatnot.

http://www.geocities.com/jeff_louie/OOP/oop9.htm
http://www.geocities.com/jeff_louie/OOP/oop37.htm

The twisted definition of runtime polymorphism is: Runtime polymorphism
involves programming to a type, such that the implementation details can
be
different and are discoverable at runtime. When programming to a type,
the
caller does not know the class of the object, only that the object
implements the
type of interest.

Regards,
Jeff
 
P

Peter Duniho

tshad said:
It is and helps.

Hopefully you are still taking the example with a grain of salt. :)
I am curious about something in the program.

The interface it uses is IAnimal. So everything that inherits from IAnimal
must have a MakeSound Method.

public interface IAnimal
{
string MakeSound();
}

True. However, IMHO the sample code has a basic design problem. That
is, in using every-day words it creates a false hierarchy. This is
compounded by what is in my opinion imprecise use of the term "inherits"
on your part.

In particular, I prefer to describe an interface as being "implemented"
by a class, rather than "inherited". To me, "inherited" implies that
the class actually gets some already-implemented functionality.
Obviously this is not the case for interfaces.

Likewise, in C# a class can only directly inherit one other class. So
what does it mean for a class to "inherit" multiple interfaces? I
understand that one really means it implements multiple interfaces, but
IMHO one should be precise about saying that instead.

This imprecision might not be so bad, except that in the example code
from that blog, it's my opinion that IAnimal is a bad interface. There
should instead be an "Animal" base class that actually _is_ inherited.
This theoretical "Animal" class would _implement_ basic behaviors that
all animals share.

As an example of an interface, I might create a "IVocalize" interface,
which would contain the "MakeSound()" method. Not all animals do make
sounds, and so by doing it this way, all animals would have a common
shared base class "Animal" that really is universal to all animals,
while those that can intentionally make sounds would _implement_ the
"IVocalize" interface themselves in whatever way was appropriate to that
particular animal.

(Ignoring for the moment the biological issue that for all we know,
_all_ animals do in fact intentionally make sounds, and the only true
division is "those that we know make sounds, and those that make sounds
but which we don't actually know about". Who knows? Maybe it'll turn
out that even bacteria and amoebas make sounds :) ).

IMHO, viewing it that way makes it much more clear the difference
between an interface and an inherited class.

Finally, while I think that others have already touched on this, I'll
respond to your question "And if I have to implement all the functions
described in the Interface, what am I really inheriting? Why not just
use an abstract class to do this?"

The answer to "what am I really inheriting?" is that you are not
inheriting _anything_ when you use an interface. You are declaring in
your class an agreement to fulfill a specific contract, to define
certain elements as part of your class so that other code can look at
your class and be assured that it _implements_ those elements.

If you want to _inherit_ some implementation, then you need to use an
actual class that defines that implementation. But in C# you can only
inherit one class, so choose that class wisely. :)

An abstract class performs double-duty as an inheritable implementation
with some abstract elements. If the abstract class contains _only_
abstract declarations, then it would probably be better to define it as
an interface. The exception would be if you really want to restrict
inheritors so that they cannot inherit any other class. But I think
that a design where that restriction is actually desirable probably
doesn't come up that often.

An abstract class that does provide some implementation is sort of the
best (and worst :) ) of both worlds. You get to inherit that basic
implementation, while also being provided a contract that your own class
is required to implement, fulfilling the complete API described by the
abstract class.

You had some other specific questions about the blog code sample, so...
[...]
One question is: Why don't they have ToString() as part of the Interface?

ToString() is part of the Object class definition. Object provides a
default implementation, so all classes already have ToString(). If you
want to override the default behavior in your own class, you may.
There's no need for any interfaces to also include it though.

This is related to your apparent misunderstanding of the difference
between inheriting a class and implementing an interface. In the
example code, Cat doesn't inherit IAnimal, it implements it. Cat _does_
inherit Object (all classes do, whether explicitly declared that way or
not), and so it already has a ToString() method.
Is the reason for having the IAnimal interface just so they can force a
method?

The reason for having "IAnimal" is to declare a specific set of methods
(in this case, just one) that a class promises to implement. That way,
other code can ask for something that's just an "IAnimal" without caring
what class it actually is. That other code only is interested in the
behavior defined in "IAnimal", and so that's the interface implemented
by any other classes that want to work with the code that needs an
"IAnimal".
Also, what is the difference between the animal classes that inherited from
IAnimal:

public class Cat : IAnimal

and this class that IS IAnimal?

public class AnimalFactory
{
public static IAnimal GetAnimal(string key)
{
[...code snipped...]
}
}

This was confusing to me.

I hope I've already been clear that Cat doesn't inherit IAnimal.
However, I also want to point out that the class AnimalFactory is also
definitely _not_ an IAnimal, nor is it true that the method GetAnimal
"is IAnimal". The method returns an instance of an object that
implements the IAnimal interface; that's all. The method itself is not
an IAnimal, nor is it any kind of class or interface at all. It's a method.
In the case of the animals they were not an IAnimal class but a bird or cat
class and had to have MakeSound() method. But the above GetAnimal() method
IS an IAnimal Class and doesn't have the MakeSound() method.

Nope. The method is not an IAnimal. There's no such thing as an
IAnimal class in the example code, so it definitely can't be "an IAnimal
Class". But it also isn't anything that _could_ be a class or _could_
implement an interface. Only classes can do that. A method is just
that: a method. A method can't have another method in C#, not could it
implement an interface, nor could it be treated as a class.
[...]
You may need to post a working sample, because you're asking the group to
evaluate...your evaluation... of another person's code.
So its hard to see what he is doing.

My mistake.

I was planning on pasting it in but must have forgot to paste it in.

Thanks for the code. It makes it much easier to understand your
original question.

Now, as far as the specific interfaces go...

In both cases, the interfaces are declaring some specific behavior that
a given class can promise, by declaration, to implement. In this case,
the Student class declares that it implements IComparable and IDisplayable.

In doing so, it essentially enters into a contract with any code that
might use an instance of a Student that it will implement the methods in
those interfaces: IComparable.CompareTo() and IDisplayable.GetString().
By doing so, other code can use the Student instance without knowing
that it's a Student at all. All that other code needs to know is the
interface it's implemented.

So, there one place where the code only needs to know that the instances
are comparable, so that it can sort them. Thus that code treats the
Student as an IComparable, and because Student implements that
interface, it can be sorted, without the code doing the sorting knowing
anything else about the class.

Likewise, IDisplayable. There's code that wants to be able to display
the instance somehow using a string value, without caring about anything
else about the class other than it can return a string for display purposes.

In the example code, there are then two completely different, unrelated
classes that both implement both interfaces. And then there's code that
performs some work on class instances, but only by using the declared
interfaces. By doing so, that code can handle both the Student
instances and the Bird instances without knowing anything about those
classes except the specific interface those classes implement and which
are required for the specific operation.

One thing I don't particularly like about the example is that the
IDisplayable interface seems redundant to me, since in C# all objects
already inherit Object which has ToString(). There's nothing wrong with
the code per se, but it seems to me that the example would be more clear
if it had defined an interface that didn't overlap an existing language
feature.

Pete
 
T

tshad

I think a lot of people have difficulty understanding Interfaces and
Abstract classes at first. I find that I rarely use an abstract class
and more often use Interfaces because of some of the constraints regarding
inheritance vs. implements. A good example of the use of an interface is
for an application that allows add-ins or plug-ins to it. Outlook for
example uses an Interface that all Add-ins must implement. This allows
Outlook to talk to each add-in but allow each add-in to function its own
way.

But if I have an abstract such as:

abstract class Drawable
{
public abstract String DrawYourself();
}

Is this really the same as:

interface IDrawable
{
String DrawYourself();
}

The only difference I see here (other than the keyword differences) is the
fact that you can only inherit 1 abstract class and can implement multiple
interfaces.

In both cases, I have to implement all the methods, correct?

In this test program, I get an error because I didn't implement the
DrawYourself method in the Circle class. I had thought that in the
Interface you had to implement ALL the methods but that wasn't the case in
the Abstract Classes (obviously I was wrong).

*************************************************
using System;

namespace TestBed
{
abstract class Drawable
{
public abstract String DrawYourself();
}

class Circle : Drawable
{
}
class Square : Drawable
{
public override string DrawYourself()
{
return "This is the Square";
}
}

/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Circle theCircle = new Circle();
Console.WriteLine("At the Circle display = " + theCircle.DrawYourself());
Square theSquare = new Square();
String theString;
theString = theSquare.DrawYourself();
Console.WriteLine("At the Square display = " + theString);
Console.Read();
}
}
}
*************************************************

Thanks,

Tom
 
P

Peter Duniho

tshad said:
But if I have an abstract such as:

abstract class Drawable
{
public abstract String DrawYourself();
}

Is this really the same as:

interface IDrawable
{
String DrawYourself();
}

Define "the same". Obviously, it's not strictly the same. But yes, in
that very basic example, the net effect is essentially the same.
The only difference I see here (other than the keyword differences) is the
fact that you can only inherit 1 abstract class and can implement multiple
interfaces.

In both cases, I have to implement all the methods, correct?

All methods have to implemented somewhere, yes. The difference is where
they must be implemented.

An abstract class can implement some methods and leave others as
abstract. An abstract class might not implement any methods, and in
that case it's basically the same as an interface (except that only one
class can be inherited of course).

An interface cannot implement any methods. It is strictly a contract
declaration and all methods must be implemented by the class that
declares that it's using (implementing) the interface.

You do have to implement every method and property that's declared,
somewhere. Whether using an abstract class or an interface, you're not
allowed to leave something unimplemented. But an abstract class
provides the opportunity to provide some base or default implementation,
even while some other things have to be implemented by inheritors.

Pete
 
M

Michael S

tshad,

I also don't like the IAnimal interface.

A simple rule of thumb should be that a class defines what a object IS,
while an interface defines what a object CAN DO.

So, in the example you provided, IAnimal should be rename ISoundable, with
the method .MakeSound(). Now the interface can be used for animals, cars,
buttons, instruments and whatever that can make a sound. They all may sound
differently, but they all make a sound.

Interfaces should be general, like IDisposable, IClonable, IDisplayable.

Classes are vertical, interfaces are horizontal.

- Michael Starberg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top