Re: Interface question

Tech-Archive recommends: Fix windows errors by optimizing your registry



tshad wrote:
"sloan" <sloan@xxxxxxxxx> wrote in message news:umHRGkGBIHA.3900@xxxxxxxxxxxxxxxxxxxxxxx
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.

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
.



Relevant Pages

  • Re: class design questions
    ... Define your base 'person' class as an interface and inherit the concrete ... For your 'student', 'borrower' etc ... Your 'student' class wouldn't have access to the private and protected ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Interface question
    ... This is the beauty of interfaces: you don't inherit from something ... interface, and make all of the classes implement it. ... ListViewModel, which is the brains behind managing item selection, ... to make another control that could interact with any control that was ...
    (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)