views:

1483

answers:

7

Today somebody told me that interface implementation in C# is just "Can-Do" relationship, not "Is-A" relationship. This conflicts with my long-time believing in LSP(Liskov Substitution Principle). I always think that all inheritance should means "Is-A" relationship.

So, If interface implementation is just a "Can-Do" relationship. What if there is a interface "IHuman" and "IEngineer", and one class "Programmer" inherits from "IHuman" & "IEngineer"? Surely, a "Programmer" Is A "IHuman" and A "IEngineer".

If it is just "Can-Do" relationship, does it mean we cannot expect the "Programmer" instance behavior may be different between when treated as a IHuman and treated as IEngineer?

+3  A: 

I tend to think of interfaces as a contract of behaviour. Interfaces such as IComparable and IEnumerable are classic examples.

In the example you gave, IHuman and IEngineer are not really behaviours.

Mitch Wheat
A: 

If I've understood your question correctly, you were right in thinking that interfaces in C# have an Is-A relationship. For example, as you can define parameters as interfaces, types that implement interfaces are those types. Polymorphism in action.

// Your class implements an interface
class Concrete : ISomeInterface {}

// New up an instance of that class
var myClass = new Concrete();

// You have a method somewhere that takes ISomeInterface as a parameter
public void MyMethod(ISomeInterface blah){}

// You can pass your instance to that method
MyMethod(myClass);
IainMH
+6  A: 

In my experience it doesn't really help that much to think of "is-a" and "can-do" relationships. You rapidly get into problems. It's an impedance mismatch between the real world and OO, basically. However much people actually talk about modeling the real world, you fundamentally need to understand what the relationships between types mean on the platform you're using.

Sometimes interfaces can be used as capabilities, and sometimes they can represent more of a normal "is-a" relationship. I wouldn't get too hung up about it - just make sure you understand what they can do and what they can't.

Jon Skeet
Reading your book Jon. It's very good.
IainMH
@Iain: Glad you're enjoying it. Do send me feedback when you've finished :)
Jon Skeet
A: 

The designers of the .NET framework use interfaces to designate a "has a" (or "can do") relationship, whereas "is a" is implemented using inheritance.

The rationale for this can be found in the Choosing Between Classes and Interfaces section of the .NET Framework Developer's Guide:

An interface defines the signatures for a set of members that implementers must provide. Interfaces cannot provide implementation details for the members.

So, since your "Programmer" and "Engineer" example classes would most likely come with their own specific functionality, they would be more suitably implementated using inheritance.

mdb
A: 

Actually that's why most of the interface are capabilities and not names so you have

IComparable, ITestable, IEnumerable

and

Human, Animal, Dog, etc

Anyway, as it has been already mentioned you have to be pragmatic, I've got a general rule when I'm coding: never let concepts, conventions or standard practices get on the way of getting the job done, better be pragmatic than academic.

so if you're sure interfaces really fit better your design, go for it, don't worry about question such as this one.

Jorge Córdoba
A: 

Found this question rather late but I wanted to chime in.

Interfaces in C# have an is-a relationship, but not is-an-object. Rather, is-an-implementation.

In other words, for class Foo that implements IBar, the following test:

Foo myFoo = new Foo(); 
return myFoo is IBar;

literally returns true. You can also say,

IBar bar = myArrayList[3] as IBar;
Foo foo = bar as Foo;

Or, if a method requires an IBar, you can pass a Foo.

void DoSomething(IBar bar) {
}

static void Main() {
    Foo myFoo = new Foo();
    DoSomething(myFoo);
}

Obviously, an IBar has no implementation in itself, so the can-do relationship also applies.

interface IBar { void happy(); }
class Foo : IBar
{
    void happy()
    {
        Console.Write("OH MAN I AM SO HAPPY!");
    }
}
class Program
{
    static void Main()
    {
        IBar myBar = new Foo();
        myBar.happy();
    }
}

But, for that matter, the same is true of object inheritance; an object of class Foo that inherits class Bar has a can-do relationship as well as an is-a relationship, in the same way as the interface does. It's just that its implementation was pre-built for it.

The real question is, is-a-what, can-do-what? An inherited class object is-a-[parent instance] and can-do-[parent's behavior], whereas an implementation of an interface is-an-[interface implementation] and therefore can-do-[the interface behavior].

In most cases where programmatic is-a relationships are used such as those listed above, only the interface is evaluated, so both an inherited class and an implemented interface share the same is-a and can-do qualities.

HTH, Jon

stimpy77
A: 

i want my ans is this format0- * **


**** in c#