Re: Trying to understand the purpose of interfaces

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance




Bruce Wood wrote:
jm wrote:
Thank you.

Why wouldn't I have an abstract class and override the abstract method,
since all the obects inherit from the same top level object (ducks)?

Here you've hit upon why interfaces are useful in a single-inheritance
language.

What if you need to give the same capability to a wide range of objects
that aren't related by inheritance? In a single-inheritance language I
have two choices.

1. Twist the inheritance hierarchy. I can stick the functionality
somewhere in the existing hierarchy, or insert a new class that
contains that functionality somewhere in the hierarchy. Inevitably this
leads to classes that shouldn't have the functionality getting it
(because they inherit from some class for some reason other than
getting this functionality), and some classes that should have the
functionality not getting it (because they're elsewhere in the
hierarchy for some reason).

Take the duck example that was given by another poster. Do you really
want a RubberDuck inheriting from Duck? What if Duck inherits from
FlyingBird which inherits from Bird which inherits from Mammal?
RubberDucks can't fly, and they're not mammals. That's what I mean by
"twisting the inheritance hierarchy": do I shoehorn things in where
they logically don't belong just so that they can get some
functionality, just so that I can treat them as equivalent in certain
cases?

2. The other choice is to insert the functionality piecemeal. Write a
Quack method in RubberDuck, even though it doesn't inherit from Duck
and therefore the compiler has no way to know that the Duck.Quack()
method and the RubberDuck.Quack() method are semantically equivalent:
they do the same thing to disparate objects. Then I have to write ugly
code like this:

public void SoundAWarning(object thing)
{
Duck duckThing = thing as Duck;
if (duckThing != null)
{
duckThing.Quack();
}
else
{
RubberDuck rubberDuckThing = thing as RubberDuck;
if (rubberDuckThing == null)
{
throw new ArgumentException(String.Format("Argument must be
either Duck or RubberDuck, not {0}.", thing.GetType()), "thing");
}
else
{
rubberDuckThing.Quack();
}
}
}

What interfaces allow me to do is give the same functionality to
otherwise unrelated classes. With an IQuack interface definition, I can
do this:

public interface IQuack
{
void Quack();
}

public class Duck : FlyingBird, IQuack
{
public void Quack() { ... }
}

public class RubberDuck : WaterToy, IQuack
{
public void Quack() { ... }
}

Notice that RubberDuck isn't a Duck: it's a WaterToy, because that's
where it logically belongs in my inheritance hierarchy. However, it
shares some functionality with Duck, so I can write methods like this:

public void SoundAWarning(IQuack quacker)
{
quacker.Quack();
}

and this (admittedly silly) method doesn't need to know whether it was
passed a Duck (a living creature) or a RubberDuck (a water toy). All it
needs to know is that the object passed it is capable of quacking in
some fashion or other. So, SoundAWarning accepts a group of objects
that cuts across the inheritance hierarchy in an arbitrary way.

Now, this may seem a nicety until you realize that all of this is
understood by and enforced by the compiler. Now that you've told the
compiler that SoundAWarning accepts only objects that implement IQuack,
the compiler will check that you only ever pass it a Duck or a
RubberDuck (or something that inherits from either of these) and
nothing else. If you recall my ugly original SoundAWarning method
above, it took an "object" as its argument, effectively telling the
compiler, "allow the caller to pass me anything at all, and I'll figure
out if it's valid at runtime." You've moved a validity check from
runtime to compile time, and you have tighter, cleaner, clearer code.
It's all good.

Very helpful. I see what you are saying and understand. This makes
sense on why it is adventageous to use an Interface, in this case. I
still have yet to use them myself, but I do understand.

Do interfaces get used in ASP.NET or is that more of an executable
world?

Thank you.

.



Relevant Pages

  • Re: Trying to understand the purpose of interfaces
    ... Twist the inheritance hierarchy. ... Take the duck example that was given by another poster. ... Quack method in RubberDuck, even though it doesn't inherit from Duck ... With an IQuack interface definition, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Trying to understand the purpose of interfaces
    ... Twist the inheritance hierarchy. ... contains that functionality somewhere in the hierarchy. ... Take the duck example that was given by another poster. ... Quack method in RubberDuck, even though it doesn't inherit from Duck ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: duck-type-checking?
    ... duck and should go back to inheritance. ... there are times when inheritance just won't do, ... original class could be used. ... but the ones from the factory class don't change, ...
    (comp.lang.python)
  • Re: delegation vs. inheritance
    ... IMHO the word inheritance is not choosen well. ... In fact, you can inherit rectangle from square or square from rectangle, ... it quacks like a duck, ...
    (comp.object)
  • Re: Code reuse
    ... You asked specifically about 2 things: Inheritance and Interfaces. ... functionality, rather than functions existing outside of any class. ... re-use the base class and its functionality in each derived class. ...
    (microsoft.public.dotnet.framework.aspnet)