Re: Interface question

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



The choice between interfaces (which automatically imply
polymorphism... if you aren't using them in only one class then they
aren't terribly useful), inheritance polymorphism, and abstract classes
really has to do with the design of your class hierarchy.

This is the beauty of interfaces: you don't inherit from something
because "I need that functionality in my derived class". Well,
sometimes you do, just to be lazy (guilty). What you're supposed to do,
however, is inherit from a parent class because, in real-world terms,
what you're making "is a" specialized case of the parent class.

So, a Dog class would inherit from the Mammal class, because a Dog "is
a" Mammal. Or, you might have two types of PurchaseOrder: an
InternalPurchaseOrder and an ExternalPurchaseOrder. You arrange these
in an inheritance hierarchy because they are logically related.

So, in the case of the purchase orders, you can write code that deals
with PurchaseOrder in general, without worrying about whether it is an
InternalPurchaseOrder or an ExternalPurchaseOrder. Some of your code
will be that way: it won't matter which one you're dealing with. That's
inheritance polymorphism.

However, when you design these three classes, you have to ask yourself
if a PurchaseOrder is a "real" thing in your business: can you make
one, without it being internal or external? In some businesses, there
may be a third type of purchase order that is sort of a basic purchase
order, but in most businesses, the answer will be "no". So, you make
PurchaseOrder abstract: it's an artifact of your class hierarchy... it
doesn't represent a real business object. You need it, because an
InternalPurchaseOrder "is _not_ a" ExternalPurchaseOrder, and an
ExternalPurchaseOrder "is _not_ a" InternalPurchaseOrder, but you still
want them to be related, so you make this fake ("abstract") class that
is the "parent" of them both, so you can, in some of your code, treat
them as equivalent. That's polymorphism through abstract classes.

So, the difference between those two is whether the parent class is
something that logically exists in its own right, or is just a
side-effect of the way you want to arrange your class hierarchy.

Interfaces come into play when the classes you want to treat as
equivalent for some purposes have _nothing_ in common as far as the
class hierarchy is concerned. The only thing they have in common is
that they all offer the same functionality. So, rather than building a
tortured class hierarchy to try to make all of these classes have a
common parent where you can put the functionality, you declare an
interface, and make all of the classes implement it. Then you can write
code that treats the classes as equivalent.

For example, I just built a special kind of ListView, and a special
kind of Panel in WinForms. They are both backed by something called a
ListViewModel, which is the brains behind managing item selection,
sorting, etc. However, I can't have both of these classes inherit from
a common ancestor: they have to inherit from ListView and Panel,
respectively.

That wasn't a problem up until this week, when I decided that I wanted
to make another control that could interact with any control that was
backed by a ListViewModel. Now, suddenly, I have a class that wants to
treat these other two classes (and any others I may build) as
equivalent, but they have no common ancestor (that I can modify). So, I
created an interface called IHasListViewModel, with one property:
Model. Now I can write my new control to search for and interact with
any control that implements the IHasListViewModel interface, and it
will know that it can get the model and talk to it, because any control
implementing that interface has to have a ListViewModel behind it.

Notice that, in a single-inheritance language like C#, that was the
_only_ way to solve the problem, other than the totally gross solution
of having my new control know, explicitly, about every class I make
that has ListViewModel, like this:

if (aControl is ListViewForSelfKeyedCollection)
{
ListViewForSelfKeyedCollection lv =
(ListViewForSelfKeyedCollection)aControl;
}
if (aControl is ProfileImageGallery)
{
ProfileImageGallery pig = (ProfileImageGallery)aControl;
}
if (aControl is LabelForSelfKeyedCollection)
{
... etc.

Ewwww... yuck. Now I have to modify my little helper control every time
I add a new one of these. Gross. With the interface, I just say:

if (aControl is IHasListViewModel)
{
IHasListViewModel lvm = (IHasListViewModel)aControl;
ListViewModel model = lvm.Model;
... off to the races ...
}

Much better, no?

.



Relevant Pages

  • Re: Interface question
    ... The interface it uses is IAnimal. ... in C# a class can only directly inherit one other class. ... 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. ... 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: ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Pulling my hair out, I need some help
    ... The reason I said not Inherited was that the OP said "an Interface ... that all DLL need to inherit to use". ... is that the plug-in must meet. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Why Java interface?
    ... In C++, there are multiple inheritances; but in Java, a class can ... inherit only one super class. ... interface is ...
    (comp.lang.java.programmer)
  • same old question: interface Vs. Abstract class
    ... Interface keyword adv: Multiple inheritance like C++. ... class B extends Character{ ... public static void main{ ... Aircraft inherit from FlyingThingand NonLivingThing. ...
    (comp.lang.java.help)