473,406 Members | 2,619 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Trying to understand interfaces

RSH
Hi,

I have been reading on interfaces working on samples I've run across on the
web. For the life of me I cannot seem to grasp them.

It appears to me that interfaces are simply blueprints to a class, that when
implemented, they require the implementing calss to make sure that each of
the properties, functions etc. are handled by the class. (????)

What I am really having a problem with is how they overcome the limitation
of multiple inheritance? It would appear that interfaces simply require that
a class handles a predetermined number of properties events etc. So if I
have a class that implements an interface and I need to add functionality to
that class...I still have to add it to the interface and handle it in the
initial class...this seems redundant to me. Not to mention modifying the
interface to include the new required functionality, now makes all other
classes that implement the interface "break" and now require that I modify
all classes that implement the interface to handle the newly added
functionality.

Now I openly admit I am no OOP guru, and I am simply trying to understand
interfaces...I am certainly not bashing them.

The code below illustrates my initial attempt at understanding
interfaces...pieced together from a few tutorials on the web.

The classes and intefaces apper below. and the instantiation of the objects
appears at the top...and will probably shed light on my lack of
understanding of interfaces.

The first instantiation illustrates the use of the interfaces:
public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

IPencil p = new Pencil();

p.Type = "Pencil";

IPencil mp = new MechanicalPencil();

mp.Type = "MechanicalPencil";

IPencil pen = new Pen();

pen.Type = "Pen";

PencilSharpener sharpener = new PencilSharpener();

sharpener.Sharpen(p);

sharpener.Sharpen(mp);

sharpener.Sharpen(pen);

}

Now where I get confused is that I can quite simply get the same results by
bypassing the interfaces and never calling the PencilSharpener class:

protected void Page_Load(object sender, EventArgs e)

{

IPencil p = new Pencil();

p.Type = "Pencil";

p.OnSharpened();

IPencil mp = new MechanicalPencil();

mp.Type = "MechanicalPencil";

IPencil pen = new Pen();

pen.Type = "Pen";

//PencilSharpener sharpener = new PencilSharpener();

//sharpener.Sharpen(p);

//sharpener.Sharpen(mp);

//sharpener.Sharpen(pen);

}

So this is where my paridigm needs some shifting :-)

Can you please help shed some light on this? Thank you very much!

Ron


// Interfaces +++++++++++++++++++++++++++++++++

//Pencil Interface

public interface IPencil

{

string Type { get; set; }

int CurrentSharpness { get; set; }

bool IsSharp { get; }

void Write();

void OnSharpened();

}

//Pencil Sharpener Interface

public interface IPencilSharpener

{

void Sharpen(IPencil pencil);

}



// Classes +++++++++++++++++++++++++++++++++++++

// Pencil Class

public class Pencil : IPencil

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public Pencil()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set {

m_type = value;

m_message = "This is my " + m_type + " writing away!";

m_sharpenedMessage = "This is one sharp " + m_type + "!";

}

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = value; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

// Function

public void Write()

{

foreach (char c in m_message)

{

if (m_Sharpened == false)

{

if (IsSharp)

{

HttpContext.Current.Response.Write(c);

}

else

{

HttpContext.Current.Response.Write("#");

}

}

else

{

HttpContext.Current.Response.Write(c);

}

m_charsUsed++;

}

HttpContext.Current.Response.Write("<BR>");

}

// Function

public void OnSharpened()

{

while(this.m_currentSharpness < m_message.Length)

{

m_charsUsed = 0;

m_currentSharpness++;

Write();

}

m_Sharpened = true;

m_message = m_sharpenedMessage;

Write();

}

public void Sharpen(IPencil pencil)

{

pencil.OnSharpened();

}

}

// Pencil Sharpener Class

public class PencilSharpener : IPencilSharpener

{

public void Sharpen(IPencil pencil)

{

HttpContext.Current.Response.Write("<br>Begin sharpening " + pencil.Type +
"...<br>");

pencil.OnSharpened();

}

}

// Pen Class

class Pen : IPencil

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public Pen()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set { m_type = value; }

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = 0; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void OnSharpened()

{

m_Sharpened = true;

m_message = "A Pen cannot be sharpened!.";

Write();

}

}

// Mechanical Pencil Class

class MechanicalPencil : IPencil, IPencilSharpener

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public MechanicalPencil()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set { m_type = value; }

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = value; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

// Function

public void Write()

{

foreach (char c in m_message)

{

if (m_Sharpened == false)

{

if (IsSharp)

{

HttpContext.Current.Response.Write(c);

}

else

{

HttpContext.Current.Response.Write("#");

}

}

else

{

HttpContext.Current.Response.Write(c);

}

m_charsUsed++;

}

HttpContext.Current.Response.Write("<BR>");

}

// Function

public void OnSharpened()

{

m_Sharpened = true;

m_message = "The Mechanical Pencil is self sharpening.";

Write();

}

public void Sharpen(IPencil pencil)

{

}

}

}


Oct 20 '06 #1
22 2039
Interfaces are meant for classes that have the same behavior, but different
implementation for that behavior.

For example, a Person object might implement a Move method one way - by
walking.

A Car object might implement a Move method another way - by driving.

However, a Person and a Car, have nothing else in common. They can't share a
common ancestor.

But they can both implement the same interface. And someone with a
collection of objects implementing this interface, can call the Move method
on each of them, without regard as to whether the object is a Car, a Person,
or something else. Because they all implement the same interface, they can
all be moved.

An interface is not a blueprint for a class. If you have only one class
implementing the interface, then you shouldn't have an interface. And if
you have multiple classes implement the interface, but they all have the
same implementation, then you should be using inheritence.

"RSH" <wa*************@yahoo.comwrote in message
news:OX****************@TK2MSFTNGP02.phx.gbl...
Hi,

I have been reading on interfaces working on samples I've run across on
the web. For the life of me I cannot seem to grasp them.

It appears to me that interfaces are simply blueprints to a class, that
when implemented, they require the implementing calss to make sure that
each of the properties, functions etc. are handled by the class. (????)

What I am really having a problem with is how they overcome the limitation
of multiple inheritance? It would appear that interfaces simply require
that a class handles a predetermined number of properties events etc. So
if I have a class that implements an interface and I need to add
functionality to that class...I still have to add it to the interface and
handle it in the initial class...this seems redundant to me. Not to
mention modifying the interface to include the new required functionality,
now makes all other classes that implement the interface "break" and now
require that I modify all classes that implement the interface to handle
the newly added functionality.

Now I openly admit I am no OOP guru, and I am simply trying to understand
interfaces...I am certainly not bashing them.

The code below illustrates my initial attempt at understanding
interfaces...pieced together from a few tutorials on the web.

The classes and intefaces apper below. and the instantiation of the
objects appears at the top...and will probably shed light on my lack of
understanding of interfaces.

The first instantiation illustrates the use of the interfaces:
public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

IPencil p = new Pencil();

p.Type = "Pencil";

IPencil mp = new MechanicalPencil();

mp.Type = "MechanicalPencil";

IPencil pen = new Pen();

pen.Type = "Pen";

PencilSharpener sharpener = new PencilSharpener();

sharpener.Sharpen(p);

sharpener.Sharpen(mp);

sharpener.Sharpen(pen);

}

Now where I get confused is that I can quite simply get the same results
by bypassing the interfaces and never calling the PencilSharpener class:

protected void Page_Load(object sender, EventArgs e)

{

IPencil p = new Pencil();

p.Type = "Pencil";

p.OnSharpened();

IPencil mp = new MechanicalPencil();

mp.Type = "MechanicalPencil";

IPencil pen = new Pen();

pen.Type = "Pen";

//PencilSharpener sharpener = new PencilSharpener();

//sharpener.Sharpen(p);

//sharpener.Sharpen(mp);

//sharpener.Sharpen(pen);

}

So this is where my paridigm needs some shifting :-)

Can you please help shed some light on this? Thank you very much!

Ron


// Interfaces +++++++++++++++++++++++++++++++++

//Pencil Interface

public interface IPencil

{

string Type { get; set; }

int CurrentSharpness { get; set; }

bool IsSharp { get; }

void Write();

void OnSharpened();

}

//Pencil Sharpener Interface

public interface IPencilSharpener

{

void Sharpen(IPencil pencil);

}



// Classes +++++++++++++++++++++++++++++++++++++

// Pencil Class

public class Pencil : IPencil

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public Pencil()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set {

m_type = value;

m_message = "This is my " + m_type + " writing away!";

m_sharpenedMessage = "This is one sharp " + m_type + "!";

}

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = value; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

// Function

public void Write()

{

foreach (char c in m_message)

{

if (m_Sharpened == false)

{

if (IsSharp)

{

HttpContext.Current.Response.Write(c);

}

else

{

HttpContext.Current.Response.Write("#");

}

}

else

{

HttpContext.Current.Response.Write(c);

}

m_charsUsed++;

}

HttpContext.Current.Response.Write("<BR>");

}

// Function

public void OnSharpened()

{

while(this.m_currentSharpness < m_message.Length)

{

m_charsUsed = 0;

m_currentSharpness++;

Write();

}

m_Sharpened = true;

m_message = m_sharpenedMessage;

Write();

}

public void Sharpen(IPencil pencil)

{

pencil.OnSharpened();

}

}

// Pencil Sharpener Class

public class PencilSharpener : IPencilSharpener

{

public void Sharpen(IPencil pencil)

{

HttpContext.Current.Response.Write("<br>Begin sharpening " + pencil.Type +
"...<br>");

pencil.OnSharpened();

}

}

// Pen Class

class Pen : IPencil

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public Pen()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set { m_type = value; }

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = 0; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void OnSharpened()

{

m_Sharpened = true;

m_message = "A Pen cannot be sharpened!.";

Write();

}

}

// Mechanical Pencil Class

class MechanicalPencil : IPencil, IPencilSharpener

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public MechanicalPencil()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set { m_type = value; }

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = value; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

// Function

public void Write()

{

foreach (char c in m_message)

{

if (m_Sharpened == false)

{

if (IsSharp)

{

HttpContext.Current.Response.Write(c);

}

else

{

HttpContext.Current.Response.Write("#");

}

}

else

{

HttpContext.Current.Response.Write(c);

}

m_charsUsed++;

}

HttpContext.Current.Response.Write("<BR>");

}

// Function

public void OnSharpened()

{

m_Sharpened = true;

m_message = "The Mechanical Pencil is self sharpening.";

Write();

}

public void Sharpen(IPencil pencil)

{

}

}

}


Oct 20 '06 #2
Interfaces also allow you to group areas of functionality which makes
developing simpler.
For example imagine a wheel object representing a wheel with a tyre on
it. You might expect to see methods and properties like , width,
height, tread pattern, spoke style, valve, inflate, polish, deflate,
tyremake, hubmake, tyremanufacturer, hubmanufacturer.

Now when you're programming against that wheel you're going to see a
huge list of properties and it might not be immediately clear what they
do.
Now have a wheel object that implements IHub and ITyre things become
clearer. you know IHub.polish will polish the hub, previously you might
have inadvertantly polished the tyre. You can also now remove
tyremanufacturer and hubmanufacturer and simply have manufacturer on
each of the interfaces.

Oct 20 '06 #3
RSH
Am I correct in that they provide no real direct functionality themselves?
Instead they simply provide a way to ensure that instantiating objects
comply a predetermined set of rules. ...And provide a mechanism for future
development against the class that enlightens the developers on the class's
mandatory properties, and functions?
"DeveloperX" <nn*****@operamail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
Interfaces also allow you to group areas of functionality which makes
developing simpler.
For example imagine a wheel object representing a wheel with a tyre on
it. You might expect to see methods and properties like , width,
height, tread pattern, spoke style, valve, inflate, polish, deflate,
tyremake, hubmake, tyremanufacturer, hubmanufacturer.

Now when you're programming against that wheel you're going to see a
huge list of properties and it might not be immediately clear what they
do.
Now have a wheel object that implements IHub and ITyre things become
clearer. you know IHub.polish will polish the hub, previously you might
have inadvertantly polished the tyre. You can also now remove
tyremanufacturer and hubmanufacturer and simply have manufacturer on
each of the interfaces.

Oct 20 '06 #4

RSH wrote:
Am I correct in that they provide no real direct functionality themselves?
Instead they simply provide a way to ensure that instantiating objects
comply a predetermined set of rules. ...And provide a mechanism for future
development against the class that enlightens the developers on the class's
mandatory properties, and functions?
"DeveloperX" <nn*****@operamail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
Interfaces also allow you to group areas of functionality which makes
developing simpler.
For example imagine a wheel object representing a wheel with a tyre on
it. You might expect to see methods and properties like , width,
height, tread pattern, spoke style, valve, inflate, polish, deflate,
tyremake, hubmake, tyremanufacturer, hubmanufacturer.

Now when you're programming against that wheel you're going to see a
huge list of properties and it might not be immediately clear what they
do.
Now have a wheel object that implements IHub and ITyre things become
clearer. you know IHub.polish will polish the hub, previously you might
have inadvertantly polished the tyre. You can also now remove
tyremanufacturer and hubmanufacturer and simply have manufacturer on
each of the interfaces.
Yeah, you hear alot of people describe them as contracts. You know if
it implements an interface it supports what ever functionality is
provided by the interface.

Oct 20 '06 #5
Yup.
They're a real boon in things like distributed applications where the server
knows of the interface but has no way of knowing the concrete type
definitions.
They're ESPECIALLY useful for testing, so to test your classes you send them
a "mock" object that implements the interface being used, but rather then
doing anything useful it just records how the interface is being used so you
can make sure it's being used correctly.

The problem with the example you provided is that your interface was
IPencil, then you ended up trying to force a Pen into being a pencil and a
mechanised pencil into being a pencil.
It should have been IWritingImplement or something like that. OnSharpen
should not have existed, you should have tried mebbe a different interface
like IBreakable with
bool IsBroken and
void Fix(IServiceProvider services);

You could then "fix" the pencil by sharpening it, the pen by... buying a new
pen and the mechanical one by getting an engineer from the services and
making him fix it.
That would probably given you better abstraction and have made more sense.
Also the type property is not necessary. All objects have GetType().Name on
them already.

HTH

Simon Tamman

"RSH" <wa*************@yahoo.comwrote in message
news:uL**************@TK2MSFTNGP02.phx.gbl...
Am I correct in that they provide no real direct functionality themselves?
Instead they simply provide a way to ensure that instantiating objects
comply a predetermined set of rules. ...And provide a mechanism for
future
development against the class that enlightens the developers on the
class's
mandatory properties, and functions?
"DeveloperX" <nn*****@operamail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
Interfaces also allow you to group areas of functionality which makes
developing simpler.
For example imagine a wheel object representing a wheel with a tyre on
it. You might expect to see methods and properties like , width,
height, tread pattern, spoke style, valve, inflate, polish, deflate,
tyremake, hubmake, tyremanufacturer, hubmanufacturer.

Now when you're programming against that wheel you're going to see a
huge list of properties and it might not be immediately clear what they
do.
Now have a wheel object that implements IHub and ITyre things become
clearer. you know IHub.polish will polish the hub, previously you might
have inadvertantly polished the tyre. You can also now remove
tyremanufacturer and hubmanufacturer and simply have manufacturer on
each of the interfaces.


Oct 20 '06 #6
PS

"RSH" <wa*************@yahoo.comwrote in message
news:OX****************@TK2MSFTNGP02.phx.gbl...
Hi,

I have been reading on interfaces working on samples I've run across on
the web. For the life of me I cannot seem to grasp them.

It appears to me that interfaces are simply blueprints to a class, that
when implemented, they require the implementing calss to make sure that
each of the properties, functions etc. are handled by the class. (????)

What I am really having a problem with is how they overcome the limitation
of multiple inheritance? It would appear that interfaces simply require
that a class handles a predetermined number of properties events etc. So
if I have a class that implements an interface and I need to add
functionality to that class...I still have to add it to the interface and
handle it in the initial class...this seems redundant to me. Not to
mention modifying the interface to include the new required functionality,
now makes all other classes that implement the interface "break" and now
require that I modify all classes that implement the interface to handle
the newly added functionality.

Now I openly admit I am no OOP guru, and I am simply trying to understand
interfaces...I am certainly not bashing them.

The code below illustrates my initial attempt at understanding
interfaces...pieced together from a few tutorials on the web.
First I would not think a Pen is a Pencil so your interface might be better
as IWritingInstrument.

IWritingInstrument pencil = new Pencil();
IWritingInstrument mp = new MechanicalPencil();
IWritingInstrument pen = new Pen();

sharpenWritingInstrument(pencil);
sharpenWritingInstrument(mp);
sharpenWritingInstrument(pen);

private void sharpenWritingInstrument(IWritingInstrument wi)
{
if(wi.IsBlunt)
wi.Sharpen();
}

PS

Oct 20 '06 #7
"DeveloperX" <nn*****@operamail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
Now have a wheel object that implements IHub and ITyre things become
clearer.
I think this would not be a good idea, because a wheel is not a hub nor is
it a tire. A wheel is composed of these things, so a wheel has a hub and a
tire.

///ark
Oct 20 '06 #8
Hi Ron,

<snip>
It appears to me that interfaces are simply blueprints to a class, that when
implemented, they require the implementing calss to make sure that each of
the properties, functions etc. are handled by the class. (????)
You can implement an interface and leave all of the members empty, or throw
NotSupportExceptions, or whatever you want. They can't enforce that the
members are handled in any certain way. Instead interfaces define a public
contract that an implementing class must provide to its consumers; enforced by
compilers [and the CLR?].

You can do whatever you want in the interface so long as it doesn't break the
public contract, though certain interfaces do imply constraints on how the
interface should be implemented. i.e., An interface's public behavior. One
such example is the following:

interface IDoThings
{
bool CanDoSomethingFoo { get; }
bool CanDoSomethingBar { get; }

void DoSomethingFoo();
void DoSomethingBar()
}

It will be obvious to callers that CanDoSomethingFoo could be verified as true
before attempting to call DoSomethingFoo. Therefore, implementations must
make sure that CanDoSomethingFoo returns whether DoSomethingFoo can be called.
In this respect interfaces aren't "simply blueprints", but instead also imply
behavioral aspects of all their implementations.

(In .NET, you can define explicit interface implementations so that the
contract exists on the implementing class but it can only be used if the
consumer explicitly casts an instance of the class to the Type of the
explicitly-implemented interface. In other words, you can hide an
implementation of an interface, although consumers can still cast the class to
the interface if desired.)
What I am really having a problem with is how they overcome the limitation
of multiple inheritance?
(I think whether multiple inheritance is a "limitation" is up for debate.)

Regardless, interfaces can't overcome this "limitation" because they don't
provide implementation. Interfaces only provide a public contract. As a
developer you can use the public contracts provided by multiple interfaces on
your class, but you'll still have to code each implementation. In other
words, your class is not actually inheriting the functionality from another
class by implementing an interface. However, you can define multiple
interfaces and implement them on multiple classes so that all of the classes
share the same interface Types, which can't be done using inheritance, but
you'll still have to code each implementation yourself so all that you'd
really gain is shared public contracts spanning multiple concrete
implementations that you had to code anyway.
It would appear that interfaces simply require that a class handles a
predetermined number of properties events etc.
..NET doesn't require that interface members are handled, just that the public
members exist, even if only explicitly.
So if I have a class that implements an interface and I need to add
functionality to that class...I still have to add it to the interface and
handle it in the initial class...this seems redundant to me.
You don't have to do anything ;)

If you are using an interface for any of the reasons found in this thread, or
the many other reasons that haven't been mentioned, then you'll know whether
you have to add new members to the declaration of your interfaces or just the
classes that implement them. As Marina pointed out, you really don't need the
interface if you are only implementing it on one class (and you have no
intention of it being used externally), therefore it will be clear if you are
using an interface and implementing it on multiple classes, whether each class
requires the new member or only one of the particular implementations requires
the new member.

If each implementing class requires the new member, and the interface should
logically contain that member, then add the member to the interface, otherwise
define a new interface or just add the member to the requiring classes. This
is a simplistic rule that doesn't make sense in every circumstance, but is a
good starting point. Other things to consider are versioning requirements,
whether modifying the interface is worth breaking the contract, and whether an
interface is even useful for the new members at all.
Not to mention modifying the interface to include the new required
functionality, now makes all other classes that implement the interface
"break" and now require that I modify all classes that implement the
interface to handle the newly added functionality.
That's why you shouldn't add the new member unless it can be used by all of
the implementing classes. (Or more commonly, unless it can be used by most of
the implementing classes). Remember that you can always define another
interface instead for new members if only a subset of the classes implementing
the current interface can use the new members. Each class in the subset can
implement both interfaces, which is one great advantage of interfaces over
inheritance.

<snip>

--
Dave Sexton
Oct 20 '06 #9
RSH
Thanks all!

This is some really goosd stuff...and thank you Dave for that incredibly
clear explanation!!!!

Dare I post my updated code. I modified it based on my new interpretation
of interfaces.
Any comments or feedback would be greatly appreciated. I'm pretty new at
this stuff :-)

THANKS!

Ron

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

IWritingInstrument pencil = new Pencil();

pencil.Write();

pencil.IsWritingPoorly = true;

pencil.IsBroken = true;

IWritingInstrument mpencil = new MechanicalPencil();

mpencil.Write();

mpencil.IsWritingPoorly = true;

mpencil.IsBroken = true;

IWritingInstrument pen = new Pen();

pen.Write();

pen.IsWritingPoorly = true;

pen.IsBroken = true;

}

// Interfaces +++++++++++++++++++++++++++++++++

//Writing Implement Interface

public interface IRepair

{

bool IsWritingPoorly { get; set; }

void Write();

void Fix();

}

//Is Breakable Interface

public interface IReplace

{

bool IsBroken { get; set; }

void Replace();

}

//Combine Interfaces

public interface IWritingInstrument : IRepair, IReplace

{

}

// Classes +++++++++++++++++++++++++++++++++++++

// Pencil Class

public class Pencil : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public Pencil()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Dull...we will
sharpen it for you...";

Write();

Fix();

m_isWritingPoorly = false;

}

}

// Function

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void Fix()

{

m_message = "The " + this.GetType().Name + " was sharpened and is now
working great!<br>";

Write();

}

public void Replace()

{

m_message = "The " + this.GetType().Name + " was replaced.<br>";

Write();

}

}

// Pen Class

public class Pen : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public Pen()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set

{

m_message = "The " + this.GetType().Name + " appears to be out of ink...we
will refill it for you...";

Write();

Fix();

m_isWritingPoorly = false;

}

}

// Function

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void Fix()

{

m_message = "The " + this.GetType().Name + " was refilled and is now working
great!<br>";

Write();

}

public void Replace()

{

m_message = "The " + this.GetType().Name + " was replaced.<br>";

Write();

}

}

// MechanicalPencil Class

public class MechanicalPencil : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public MechanicalPencil()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set

{

m_message = "The " + this.GetType().Name + " appears to be out of lead...we
will replace the lead for you...";

Write();

Fix();

m_isWritingPoorly = false;

}

}

// Function

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void Fix()

{

m_message = "The " + this.GetType().Name + "'s lead was replaced and is now
working great!<br>";

Write();

}

public void Replace()

{

m_message = "The " + this.GetType().Name + " was replaced.<br>";

Write();

}

}

}


Oct 20 '06 #10
I think you get it. The example I like to use when explaining using
interfaces is the media player

public interface IMediaPlayer
{
FastForward();
Rewind()
Play();
Stop();
}

Then you can declare classes like

MP3Player : IMediaPlayer
VideoPlayer : IMediaPlayer

Each class performs the same functions, but would be implemented very
differently. You can have common code that does something like:

IMediaPlayer mp;
string playerType = "mp3"
mp = new MP3Player();
mp.Play();
mp.Stop();

mp = new VideoPlayer();
mp.Play();
mp.Stop();

Imagine interfaces being useful if you were writing a Media player that
plays audio files, video files, DVDs, etc.

Each has the same function, but are implemented differently.

"RSH" wrote:
Thanks all!

This is some really goosd stuff...and thank you Dave for that incredibly
clear explanation!!!!

Dare I post my updated code. I modified it based on my new interpretation
of interfaces.
Any comments or feedback would be greatly appreciated. I'm pretty new at
this stuff :-)

THANKS!

Ron

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

IWritingInstrument pencil = new Pencil();

pencil.Write();

pencil.IsWritingPoorly = true;

pencil.IsBroken = true;

IWritingInstrument mpencil = new MechanicalPencil();

mpencil.Write();

mpencil.IsWritingPoorly = true;

mpencil.IsBroken = true;

IWritingInstrument pen = new Pen();

pen.Write();

pen.IsWritingPoorly = true;

pen.IsBroken = true;

}

// Interfaces +++++++++++++++++++++++++++++++++

//Writing Implement Interface

public interface IRepair

{

bool IsWritingPoorly { get; set; }

void Write();

void Fix();

}

//Is Breakable Interface

public interface IReplace

{

bool IsBroken { get; set; }

void Replace();

}

//Combine Interfaces

public interface IWritingInstrument : IRepair, IReplace

{

}

// Classes +++++++++++++++++++++++++++++++++++++

// Pencil Class

public class Pencil : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public Pencil()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Dull...we will
sharpen it for you...";

Write();

Fix();

m_isWritingPoorly = false;

}

}

// Function

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void Fix()

{

m_message = "The " + this.GetType().Name + " was sharpened and is now
working great!<br>";

Write();

}

public void Replace()

{

m_message = "The " + this.GetType().Name + " was replaced.<br>";

Write();

}

}

// Pen Class

public class Pen : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public Pen()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set

{

m_message = "The " + this.GetType().Name + " appears to be out of ink...we
will refill it for you...";

Write();

Fix();

m_isWritingPoorly = false;

}

}

// Function

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void Fix()

{

m_message = "The " + this.GetType().Name + " was refilled and is now working
great!<br>";

Write();
Oct 20 '06 #11
RSH
Great...now on to Delegates!!!!

Thanks everyone!
Ron

"RSH" <wa*************@yahoo.comwrote in message
news:OX****************@TK2MSFTNGP02.phx.gbl...
Hi,

I have been reading on interfaces working on samples I've run across on
the web. For the life of me I cannot seem to grasp them.

It appears to me that interfaces are simply blueprints to a class, that
when implemented, they require the implementing calss to make sure that
each of the properties, functions etc. are handled by the class. (????)

What I am really having a problem with is how they overcome the limitation
of multiple inheritance? It would appear that interfaces simply require
that a class handles a predetermined number of properties events etc. So
if I have a class that implements an interface and I need to add
functionality to that class...I still have to add it to the interface and
handle it in the initial class...this seems redundant to me. Not to
mention modifying the interface to include the new required functionality,
now makes all other classes that implement the interface "break" and now
require that I modify all classes that implement the interface to handle
the newly added functionality.

Now I openly admit I am no OOP guru, and I am simply trying to understand
interfaces...I am certainly not bashing them.

The code below illustrates my initial attempt at understanding
interfaces...pieced together from a few tutorials on the web.

The classes and intefaces apper below. and the instantiation of the
objects appears at the top...and will probably shed light on my lack of
understanding of interfaces.

The first instantiation illustrates the use of the interfaces:
public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

IPencil p = new Pencil();

p.Type = "Pencil";

IPencil mp = new MechanicalPencil();

mp.Type = "MechanicalPencil";

IPencil pen = new Pen();

pen.Type = "Pen";

PencilSharpener sharpener = new PencilSharpener();

sharpener.Sharpen(p);

sharpener.Sharpen(mp);

sharpener.Sharpen(pen);

}

Now where I get confused is that I can quite simply get the same results
by bypassing the interfaces and never calling the PencilSharpener class:

protected void Page_Load(object sender, EventArgs e)

{

IPencil p = new Pencil();

p.Type = "Pencil";

p.OnSharpened();

IPencil mp = new MechanicalPencil();

mp.Type = "MechanicalPencil";

IPencil pen = new Pen();

pen.Type = "Pen";

//PencilSharpener sharpener = new PencilSharpener();

//sharpener.Sharpen(p);

//sharpener.Sharpen(mp);

//sharpener.Sharpen(pen);

}

So this is where my paridigm needs some shifting :-)

Can you please help shed some light on this? Thank you very much!

Ron


// Interfaces +++++++++++++++++++++++++++++++++

//Pencil Interface

public interface IPencil

{

string Type { get; set; }

int CurrentSharpness { get; set; }

bool IsSharp { get; }

void Write();

void OnSharpened();

}

//Pencil Sharpener Interface

public interface IPencilSharpener

{

void Sharpen(IPencil pencil);

}



// Classes +++++++++++++++++++++++++++++++++++++

// Pencil Class

public class Pencil : IPencil

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public Pencil()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set {

m_type = value;

m_message = "This is my " + m_type + " writing away!";

m_sharpenedMessage = "This is one sharp " + m_type + "!";

}

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = value; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

// Function

public void Write()

{

foreach (char c in m_message)

{

if (m_Sharpened == false)

{

if (IsSharp)

{

HttpContext.Current.Response.Write(c);

}

else

{

HttpContext.Current.Response.Write("#");

}

}

else

{

HttpContext.Current.Response.Write(c);

}

m_charsUsed++;

}

HttpContext.Current.Response.Write("<BR>");

}

// Function

public void OnSharpened()

{

while(this.m_currentSharpness < m_message.Length)

{

m_charsUsed = 0;

m_currentSharpness++;

Write();

}

m_Sharpened = true;

m_message = m_sharpenedMessage;

Write();

}

public void Sharpen(IPencil pencil)

{

pencil.OnSharpened();

}

}

// Pencil Sharpener Class

public class PencilSharpener : IPencilSharpener

{

public void Sharpen(IPencil pencil)

{

HttpContext.Current.Response.Write("<br>Begin sharpening " + pencil.Type +
"...<br>");

pencil.OnSharpened();

}

}

// Pen Class

class Pen : IPencil

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public Pen()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set { m_type = value; }

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = 0; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void OnSharpened()

{

m_Sharpened = true;

m_message = "A Pen cannot be sharpened!.";

Write();

}

}

// Mechanical Pencil Class

class MechanicalPencil : IPencil, IPencilSharpener

{

private string m_message;

private string m_sharpenedMessage;

private string m_type;

private int m_currentSharpness;

private int m_charsUsed;

private Boolean m_Sharpened = false;

// Constructor

public MechanicalPencil()

{

m_type = string.Empty;

m_currentSharpness = 0;

m_message = string.Empty;

m_sharpenedMessage = string.Empty;

m_charsUsed = 0;

}

// Property

public string Message

{

get { return m_message; }

}

// Property

public string SharpenedMessage

{

get { return m_sharpenedMessage; }

}

// Property

public string Type

{

get { return m_type; }

set { m_type = value; }

}

// Property

public int CurrentSharpness

{

get { return m_currentSharpness; }

set { m_currentSharpness = value; }

}

// Property

public bool IsSharp

{

get { return m_charsUsed <= m_currentSharpness; }

}

// Function

public void Write()

{

foreach (char c in m_message)

{

if (m_Sharpened == false)

{

if (IsSharp)

{

HttpContext.Current.Response.Write(c);

}

else

{

HttpContext.Current.Response.Write("#");

}

}

else

{

HttpContext.Current.Response.Write(c);

}

m_charsUsed++;

}

HttpContext.Current.Response.Write("<BR>");

}

// Function

public void OnSharpened()

{

m_Sharpened = true;

m_message = "The Mechanical Pencil is self sharpening.";

Write();

}

public void Sharpen(IPencil pencil)

{

}

}

}


Oct 20 '06 #12
Sorry, I meant to write the code like this:

IMediaPlayer mp;
string playerType = "mp3"

switch(playerType)
{
case "mp3" : mp = new MP3Player(); break;
case "video" : mp = new VideoPlayer(); break;
}

mp.Play();
mp.Stop();

"rmacias" wrote:
I think you get it. The example I like to use when explaining using
interfaces is the media player

public interface IMediaPlayer
{
FastForward();
Rewind()
Play();
Stop();
}

Then you can declare classes like

MP3Player : IMediaPlayer
VideoPlayer : IMediaPlayer

Each class performs the same functions, but would be implemented very
differently. You can have common code that does something like:

IMediaPlayer mp;
string playerType = "mp3"
mp = new MP3Player();
mp.Play();
mp.Stop();

mp = new VideoPlayer();
mp.Play();
mp.Stop();

Imagine interfaces being useful if you were writing a Media player that
plays audio files, video files, DVDs, etc.

Each has the same function, but are implemented differently.

"RSH" wrote:
Thanks all!

This is some really goosd stuff...and thank you Dave for that incredibly
clear explanation!!!!

Dare I post my updated code. I modified it based on my new interpretation
of interfaces.
Any comments or feedback would be greatly appreciated. I'm pretty new at
this stuff :-)

THANKS!

Ron

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

IWritingInstrument pencil = new Pencil();

pencil.Write();

pencil.IsWritingPoorly = true;

pencil.IsBroken = true;

IWritingInstrument mpencil = new MechanicalPencil();

mpencil.Write();

mpencil.IsWritingPoorly = true;

mpencil.IsBroken = true;

IWritingInstrument pen = new Pen();

pen.Write();

pen.IsWritingPoorly = true;

pen.IsBroken = true;

}

// Interfaces +++++++++++++++++++++++++++++++++

//Writing Implement Interface

public interface IRepair

{

bool IsWritingPoorly { get; set; }

void Write();

void Fix();

}

//Is Breakable Interface

public interface IReplace

{

bool IsBroken { get; set; }

void Replace();

}

//Combine Interfaces

public interface IWritingInstrument : IRepair, IReplace

{

}

// Classes +++++++++++++++++++++++++++++++++++++

// Pencil Class

public class Pencil : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public Pencil()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Dull...we will
sharpen it for you...";

Write();

Fix();

m_isWritingPoorly = false;

}

}

// Function

public void Write()

{

HttpContext.Current.Response.Write(m_message + "<BR>");

}

// Function

public void Fix()

{

m_message = "The " + this.GetType().Name + " was sharpened and is now
working great!<br>";

Write();

}

public void Replace()

{

m_message = "The " + this.GetType().Name + " was replaced.<br>";

Write();

}

}

// Pen Class

public class Pen : IWritingInstrument

{

private string m_message;

private Boolean m_isWritingPoorly;

private Boolean m_isBroken;

// Constructor

public Pen()

{

m_isWritingPoorly = false;

m_isBroken = false;

m_message = "";

}

// Property

public Boolean IsBroken

{

get { return m_isBroken; }

set

{

m_message = "The " + this.GetType().Name + " appears to be Broken...we will
replace it for you...";

Write();

Replace();

m_isBroken = false;

}

}

// Property

public bool IsWritingPoorly

{

get { return m_isWritingPoorly; }

set
Oct 20 '06 #13
RSH
One last question...
I have two interfaces that I combine into a new one
public interface IRepair

{

bool IsWritingPoorly { get; set; }

void Write();

void Fix();

}

//Replace Interface

public interface IReplace

{

bool IsBroken { get; set; }

void Replace();

}

//Combine Interfaces

public interface IWritingInstrument : IRepair, IReplace

{

}

Now I need to add a new interface for refilling the pen. But the pencil and
Mechanical Pencil objects don't need the refill interface. So my class
declarations look like this:

public class Pencil : IWritingInstrument

{

.... the code goes here

}

public class MechanicalPencil : IWritingInstrument

{

.... the code goes here

}

But now I need to add an interface specifically for ink WritingInstruments
so I add an interface:

//Refill Interface

public interface IRefill

{

bool NeedsRefilling { get; set; }

void Refill();

}

....and my class delaration looks like this:

public class Pen : IWritingInstrument, IRefill

{

....code goes here

}

Now for my question...

In the examples so far the objects are instantiated like this:

IWritingInstrument pencil = new Pencil();

IWritingInstrument mpencil = new MechanicalPencil();

The problem is that I need the IWriting Instrument Interface, but in
addition I need the IRefill interface just for them pen, not the pencils.
In which case is it correct to create the object as follows?

I don't want the pencils to have a refill function, it doesn't make any
sense.

Pen pen = new Pen();

Basic testing shows that the interfaces still seem to require each member of
the "contract" so everything appears to be working correctly...so am I to
assume this is okay to do?

Thanks!

Ron

Oct 20 '06 #14
Hi Ron,

I recommend against using interfaces unless they will add some value. In your
examples, you haven't provided any requirements that lead me to believe
interfaces will be useful to you at all. For that reason it's hard to tell
you what you should and shouldn't do in your code. From the limited
requirements you've stated thus far, I'd recommend not using interfaces at
all.

If you are going to pass the pen that you defined in your example to a method
and if at some point in code you may pass a different implementation of
IWritingInstrument to the same method then an interface could be useful. If
not, then you probably don't need to use interfaces. Other uses for
interfaces are in COM interop and certain design patterns.

The interfaces and members you have chosen don't make much sense though. For
instance, the Write method should be on the IWritingInstrument interface, not
IRepair, because even instruments that can't break may need to Write something
:). And there is no reason for the IRepair and IReplace interfaces since they
must be implemented by all IWritingInstrument implementations anyway and you
haven't shown any external requirement for them. I think the following
solution makes more sense, considering that the interfaces you have defined
aren't based on any business requirements of which I'm unaware. My examples
afterwards use the interfaces, thus rationalizing their existence in the first
place.

interface IRefillable
{
bool ShouldRefill { get; set; }
bool CanRefill { get; }
void Refill();
}

interface IWritingInstrument
{
// replacement
bool ShouldReplace { get; }
bool CanReplace { get; }
void Replace();

// repair
bool IsWritingPoorly { get; set; }
bool IsBroken { get; set; }
bool CanRepair { get; }
void Repair();

// use
void Write(string words);
}

class Pen : IWritingInstrument, IRefillable
{
private bool broken;
public bool IsBroken { get { return broken; } set { broken = value; } }

public void Write(string words)
{
if (broken)
// don't try to write with a broken utensil!
throw new BrokenWritingInstrumentException(this); // undeclared
in my example

Console.WriteLine("Pen: " + words);

// crappy pen ;)
broken = true;
}
...
}

class Pencil : IWritingInstrument
{
public void Write(string words)
{
Console.WriteLine("Pencil: " + words);

// note that Pencil's don't break after writing, unlike Pens
}
...
}
....

The problem is that I need the IWriting Instrument Interface, but in
addition I need the IRefill interface just for them pen, not the pencils. In
which case is it correct to create the object as follows?
I don't want the pencils to have a refill function, it doesn't make any
sense.
Pen pen = new Pen();
I understand that you are using Pen pen = new Pen() because you want access to
your IRefill interface, but you could just as easily do the following:

IRefillable refillableUtensil = new Pen();

Now, with refillableUtensil, you can pass it to any method that accepts a
parameter of Type IRefillable. If you don't have any such methods defined (or
any use for IRefillable) then you don't need the interface. For instance, if
Pen is the only object that is IRefillable and you don't have any particular
reason to code against the IRefillable interface instead of the Pen class
itself, then just declare the Refill method in the Pen class and don't even
declare the interface.

Use the IWritingInstrument interface if code such as the following is desired:

void Test()
{
Pen pen = new Pen();

if (!TestWritingInstrument(pen))
Console.WriteLine("1: Pen is broken");
else
Console.WriteLine("1: Pen works just fine");

if (!TestWritingInstrument(pen))
Console.WriteLine("2: Pen is broken");
else
Console.WriteLine("2: Pen works just fine");

if (!TestWritingInstrument(new Pencil()))
Console.WriteLine("Pencil is broken");
else
Console.WriteLine("Pencil works just fine");
}

// This method doesn't know whether it's testing a Pen or a Pencil,
// which is the reason for the interface in the first place
bool TestWritingInstrument(IWritingInstrument utensil)
{
if (utensil == null)
throw new ArgumentNullException("utensil");

if (utensil.IsBroken)
// test failed!
return false;

// if IsBroken wasn't defined we could just call Write and catch
// BrokenWritingInstrumentException and then return false

utensil.Write("This is a test!");

// assume test passed
return true;
}
For the sake of using IRefillable in an example, you could have a method such
as the following:

void Write(IWritingInstrument utensil, string words)
{
if (utensil == null)
throw new ArgumentNullException("utensil");

if (utensil.ShouldReplace)
utensil.Replace();

IRefillable refillable = utensil as IRefillable;

if (refillable != null && refillable.ShouldRefill)
{
if (refillable.CanRefill)
refillable.Refill();
else if (utensil.CanReplace)
utensil.Replace();
else
throw new InvalidOperationException("The writing instrument is
empty and cannot be refilled or replaced at this time.");
}

// this method may throw BrokenWritingInstrumentException,
// which is not defined in my example
utensil.Write(words);
}
With the above method defined you can write with any IWritingInstrument and be
sure not to run out of "juice":

Write(new Pen(), "Test custom Write method");
Write(new Pencil(), "Test custom Write method");
(Please note that I haven't tested this code so it will probably require
modifications to build correctly)

--
Dave Sexton

"RSH" <wa*************@yahoo.comwrote in message
news:uf*************@TK2MSFTNGP05.phx.gbl...
One last question...
I have two interfaces that I combine into a new one
public interface IRepair

{

bool IsWritingPoorly { get; set; }

void Write();

void Fix();

}

//Replace Interface

public interface IReplace

{

bool IsBroken { get; set; }

void Replace();

}

//Combine Interfaces

public interface IWritingInstrument : IRepair, IReplace

{

}

Now I need to add a new interface for refilling the pen. But the pencil and
Mechanical Pencil objects don't need the refill interface. So my class
declarations look like this:

public class Pencil : IWritingInstrument

{

... the code goes here

}

public class MechanicalPencil : IWritingInstrument

{

... the code goes here

}

But now I need to add an interface specifically for ink WritingInstruments
so I add an interface:

//Refill Interface

public interface IRefill

{

bool NeedsRefilling { get; set; }

void Refill();

}

...and my class delaration looks like this:

public class Pen : IWritingInstrument, IRefill

{

...code goes here

}

Now for my question...

In the examples so far the objects are instantiated like this:

IWritingInstrument pencil = new Pencil();

IWritingInstrument mpencil = new MechanicalPencil();

The problem is that I need the IWriting Instrument Interface, but in
addition I need the IRefill interface just for them pen, not the pencils. In
which case is it correct to create the object as follows?

I don't want the pencils to have a refill function, it doesn't make any
sense.

Pen pen = new Pen();

Basic testing shows that the interfaces still seem to require each member of
the "contract" so everything appears to be working correctly...so am I to
assume this is okay to do?

Thanks!

Ron



Oct 20 '06 #15
RSH
Oh Dave I have way too much to learn...thank you for your assistance. Just
when i thought I was beginning to understand interfaces :-)

Thank you for your time!
Ron

"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:u1**************@TK2MSFTNGP04.phx.gbl...
Hi Ron,

I recommend against using interfaces unless they will add some value. In
your examples, you haven't provided any requirements that lead me to
believe interfaces will be useful to you at all. For that reason it's
hard to tell you what you should and shouldn't do in your code. From the
limited requirements you've stated thus far, I'd recommend not using
interfaces at all.

If you are going to pass the pen that you defined in your example to a
method and if at some point in code you may pass a different
implementation of IWritingInstrument to the same method then an interface
could be useful. If not, then you probably don't need to use interfaces.
Other uses for interfaces are in COM interop and certain design patterns.

The interfaces and members you have chosen don't make much sense though.
For instance, the Write method should be on the IWritingInstrument
interface, not IRepair, because even instruments that can't break may need
to Write something :). And there is no reason for the IRepair and
IReplace interfaces since they must be implemented by all
IWritingInstrument implementations anyway and you haven't shown any
external requirement for them. I think the following solution makes more
sense, considering that the interfaces you have defined aren't based on
any business requirements of which I'm unaware. My examples afterwards
use the interfaces, thus rationalizing their existence in the first place.

interface IRefillable
{
bool ShouldRefill { get; set; }
bool CanRefill { get; }
void Refill();
}

interface IWritingInstrument
{
// replacement
bool ShouldReplace { get; }
bool CanReplace { get; }
void Replace();

// repair
bool IsWritingPoorly { get; set; }
bool IsBroken { get; set; }
bool CanRepair { get; }
void Repair();

// use
void Write(string words);
}

class Pen : IWritingInstrument, IRefillable
{
private bool broken;
public bool IsBroken { get { return broken; } set { broken = value; } }

public void Write(string words)
{
if (broken)
// don't try to write with a broken utensil!
throw new BrokenWritingInstrumentException(this); //
undeclared in my example

Console.WriteLine("Pen: " + words);

// crappy pen ;)
broken = true;
}
...
}

class Pencil : IWritingInstrument
{
public void Write(string words)
{
Console.WriteLine("Pencil: " + words);

// note that Pencil's don't break after writing, unlike Pens
}
...
}
...

>The problem is that I need the IWriting Instrument Interface, but in
addition I need the IRefill interface just for them pen, not the pencils.
In which case is it correct to create the object as follows?
I don't want the pencils to have a refill function, it doesn't make any
sense.
Pen pen = new Pen();

I understand that you are using Pen pen = new Pen() because you want
access to your IRefill interface, but you could just as easily do the
following:

IRefillable refillableUtensil = new Pen();

Now, with refillableUtensil, you can pass it to any method that accepts a
parameter of Type IRefillable. If you don't have any such methods defined
(or any use for IRefillable) then you don't need the interface. For
instance, if Pen is the only object that is IRefillable and you don't have
any particular reason to code against the IRefillable interface instead of
the Pen class itself, then just declare the Refill method in the Pen class
and don't even declare the interface.

Use the IWritingInstrument interface if code such as the following is
desired:

void Test()
{
Pen pen = new Pen();

if (!TestWritingInstrument(pen))
Console.WriteLine("1: Pen is broken");
else
Console.WriteLine("1: Pen works just fine");

if (!TestWritingInstrument(pen))
Console.WriteLine("2: Pen is broken");
else
Console.WriteLine("2: Pen works just fine");

if (!TestWritingInstrument(new Pencil()))
Console.WriteLine("Pencil is broken");
else
Console.WriteLine("Pencil works just fine");
}

// This method doesn't know whether it's testing a Pen or a Pencil,
// which is the reason for the interface in the first place
bool TestWritingInstrument(IWritingInstrument utensil)
{
if (utensil == null)
throw new ArgumentNullException("utensil");

if (utensil.IsBroken)
// test failed!
return false;

// if IsBroken wasn't defined we could just call Write and catch
// BrokenWritingInstrumentException and then return false

utensil.Write("This is a test!");

// assume test passed
return true;
}
For the sake of using IRefillable in an example, you could have a method
such as the following:

void Write(IWritingInstrument utensil, string words)
{
if (utensil == null)
throw new ArgumentNullException("utensil");

if (utensil.ShouldReplace)
utensil.Replace();

IRefillable refillable = utensil as IRefillable;

if (refillable != null && refillable.ShouldRefill)
{
if (refillable.CanRefill)
refillable.Refill();
else if (utensil.CanReplace)
utensil.Replace();
else
throw new InvalidOperationException("The writing instrument is
empty and cannot be refilled or replaced at this time.");
}

// this method may throw BrokenWritingInstrumentException,
// which is not defined in my example
utensil.Write(words);
}
With the above method defined you can write with any IWritingInstrument
and be sure not to run out of "juice":

Write(new Pen(), "Test custom Write method");
Write(new Pencil(), "Test custom Write method");
(Please note that I haven't tested this code so it will probably require
modifications to build correctly)

--
Dave Sexton

"RSH" <wa*************@yahoo.comwrote in message
news:uf*************@TK2MSFTNGP05.phx.gbl...
>One last question...
I have two interfaces that I combine into a new one
public interface IRepair

{

bool IsWritingPoorly { get; set; }

void Write();

void Fix();

}

//Replace Interface

public interface IReplace

{

bool IsBroken { get; set; }

void Replace();

}

//Combine Interfaces

public interface IWritingInstrument : IRepair, IReplace

{

}

Now I need to add a new interface for refilling the pen. But the pencil
and Mechanical Pencil objects don't need the refill interface. So my
class declarations look like this:

public class Pencil : IWritingInstrument

{

... the code goes here

}

public class MechanicalPencil : IWritingInstrument

{

... the code goes here

}

But now I need to add an interface specifically for ink
WritingInstruments so I add an interface:

//Refill Interface

public interface IRefill

{

bool NeedsRefilling { get; set; }

void Refill();

}

...and my class delaration looks like this:

public class Pen : IWritingInstrument, IRefill

{

...code goes here

}

Now for my question...

In the examples so far the objects are instantiated like this:

IWritingInstrument pencil = new Pencil();

IWritingInstrument mpencil = new MechanicalPencil();

The problem is that I need the IWriting Instrument Interface, but in
addition I need the IRefill interface just for them pen, not the pencils.
In which case is it correct to create the object as follows?

I don't want the pencils to have a refill function, it doesn't make any
sense.

Pen pen = new Pen();

Basic testing shows that the interfaces still seem to require each member
of the "contract" so everything appears to be working correctly...so am I
to assume this is okay to do?

Thanks!

Ron




Oct 23 '06 #16
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:u1**************@TK2MSFTNGP04.phx.gbl...
>
I recommend against using interfaces unless they will add some value. In
your examples, you haven't provided any requirements that lead me to
believe interfaces will be useful to you at all. For that reason it's
hard to tell you what you should and shouldn't do in your code. From the
limited requirements you've stated thus far, I'd recommend not using
interfaces at all.
In another thread, you were looking for some agreement between us. Consider
it found. :)

///ark
Oct 23 '06 #17
Hi Mark,

I'm glad to hear that you agree with me on the point I made about the OP's use
of interfaces :)

But in our conversation I wasn't looking for agreement just for the sake of
agreeing, but instead for the sake of learning. When a conversation ends
without agreement, everyone's left with one or more competing ideas and no
solution, although I think we located the root of our difference of opinion
anyway.

--
Dave Sexton

"Mark Wilden" <mw*****@communitymtm.comwrote in message
news:O5**************@TK2MSFTNGP03.phx.gbl...
"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:u1**************@TK2MSFTNGP04.phx.gbl...
>>
I recommend against using interfaces unless they will add some value. In
your examples, you haven't provided any requirements that lead me to
believe interfaces will be useful to you at all. For that reason it's hard
to tell you what you should and shouldn't do in your code. From the
limited requirements you've stated thus far, I'd recommend not using
interfaces at all.

In another thread, you were looking for some agreement between us. Consider
it found. :)

///ark


Oct 23 '06 #18
Hi,

Dave Sexton wrote:
Hi Mark,

I'm glad to hear that you agree with me on the point I made about the OP's use
of interfaces :)

But in our conversation I wasn't looking for agreement just for the sake of
agreeing, but instead for the sake of learning. When a conversation ends
without agreement, everyone's left with one or more competing ideas and no
solution, although I think we located the root of our difference of opinion
anyway.
I think there can be learning without agreement (unless I misunderstand
what agreement really means in english). I still don't really agree with
Mark's thoughts about documenting the source code, but I have thought *a
lot* about it since we talked about that, and I think it will help me to
be more efficient about my coding.

HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch
Oct 23 '06 #19
Hi Laurent,

I didn't mean to imply that our conversation was pointless. I believe it was
helpful to me as well. I was trying to come to an agreement with Mark for the
sake of learning so we could validate or disproove our beliefs and have a
better understanding of what is the "right way of doing things". We never
came to such an agreement because we disagreed on other things that were
off-topic, as I pointed out.

I only replied with that statement because it seemed that Mark's comments were
meant to say, "here's your agreement, Dave". That's not what I wanted when I
asked to agree on something - just any agreement on anything, even something
completely unrelated such as the use of interfaces :)

--
Dave Sexton

"Laurent Bugnion" <ga*********@bluewin.chwrote in message
news:uc**************@TK2MSFTNGP05.phx.gbl...
Hi,

Dave Sexton wrote:
>Hi Mark,

I'm glad to hear that you agree with me on the point I made about the OP's
use of interfaces :)

But in our conversation I wasn't looking for agreement just for the sake of
agreeing, but instead for the sake of learning. When a conversation ends
without agreement, everyone's left with one or more competing ideas and no
solution, although I think we located the root of our difference of opinion
anyway.

I think there can be learning without agreement (unless I misunderstand what
agreement really means in english). I still don't really agree with Mark's
thoughts about documenting the source code, but I have thought *a lot* about
it since we talked about that, and I think it will help me to be more
efficient about my coding.

HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch

Oct 23 '06 #20
BTW, disprove definitely has only one O ;)

--
Dave Sexton

"Laurent Bugnion" <ga*********@bluewin.chwrote in message
news:uc**************@TK2MSFTNGP05.phx.gbl...
Hi,

Dave Sexton wrote:
>Hi Mark,

I'm glad to hear that you agree with me on the point I made about the OP's
use of interfaces :)

But in our conversation I wasn't looking for agreement just for the sake of
agreeing, but instead for the sake of learning. When a conversation ends
without agreement, everyone's left with one or more competing ideas and no
solution, although I think we located the root of our difference of opinion
anyway.

I think there can be learning without agreement (unless I misunderstand what
agreement really means in english). I still don't really agree with Mark's
thoughts about documenting the source code, but I have thought *a lot* about
it since we talked about that, and I think it will help me to be more
efficient about my coding.

HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch

Oct 23 '06 #21
On Mon, 23 Oct 2006 21:53:10 +0200, Laurent Bugnion
<ga*********@bluewin.chwrote:
>I think there can be learning without agreement
I disagree! <vbg>

--
Posted via a free Usenet account from http://www.teranews.com

Oct 23 '06 #22
Hi,

Ben Newsam wrote:
On Mon, 23 Oct 2006 21:53:10 +0200, Laurent Bugnion
<ga*********@bluewin.chwrote:
>I think there can be learning without agreement

I disagree! <vbg>
Did you at least learn something? ;-)

Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch
Oct 24 '06 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Tom | last post by:
Hello, I've recently started trying to learn C (for the fun of it!). I have been using Perl and other languages for many years, but they were always very high level, this is giving me quite a...
6
by: dotNeter | last post by:
The services, talked here, are things used in IServiceContainer, IServiceProvider, etc. In my opinion, everything can be a service, and a service is generally used for providing specific features...
27
by: jm | last post by:
I am having trouble understanding the purposes of an interface, even though the concept of interfaces is around me all the time (user interface, for example). I'm just not understanding software...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.