开发者

Doubt in using the interface?

Whenever i hear about interfaces i have the following doubt.

i have the following interface

interface Imammals
          {
           walk();
           eat();
           run();
          }

and i have two classes Human and Cat that implements this interface.

Anyway, the functionality of the methods are going to be different in both the Classes.

For Eg: walk(), the functionality differs as cat uses four legs and human uses two legs

Then, Why do i need to have a common interface which ONLY declares these methods? Is my design here faulty?

If the functionality of the methods are going to be same in both the classes, i could go for a class based inheritance where the parent implements the complete functionality and the child inherits and uses the parent class methods.

But here the interfaces help us just t开发者_高级运维o consolidate the methods declarations or is there anything more inside?

EDIT: walking(), eating(), running() was changed to walk(), eat(), run() and mammals was changes to Imammals.


In your scenario, either type-inheritance or interface-implementation would work - but interface based abstraction allows types outside of your existing type model to provide the functionality. It could be a mock object, or it could be some kind of super killer robot, that can walk run and eat but isn't really a mammal (so having it inherit from a Mammal class could be confusing or just impossible).

In particular, interfaces allow us to express this relationship neatly, while avoiding the subtle points from C# having single (type-)inheritance.


Using the interface you can have the following:

   public void walkMyAnimal(Animal animal) {
       animal.walk();
   }

without the need to know what animal exactly is passed.


Interface allows you to define behavior for inheriting classes so if you have Donkey in future then you simply implement this interface and be sure that you donkey will walk,run and eat.

Also you can use composition instead of concrete implementation if some of your objects have common behaviour.

Read a bit about Strategy pattern I think that will help.


One big advantage of interfaces is that even in languages like Java and C# where multiple inheritance is not allowed, a class can take on more than one interface. Something can be both Closable, for instance, and a List, but could not inherit from both (hypothetical) abstract base classes AbstractClosable and AbstractList.

It is also suitable for cases where you are writing a library or a plugin interface and want to provide a way for your code to use objects provided by library users or plugin writers, but you don't want (nor should you) any say in the implementation. Think of the Listener interfaces in Java, for instance. Without those, there would be no possibility of an event model, since Java doens't support callbacks.

In general, interfaces are good for cases where you want objects that have particular functionality, but the way that functionality is implemented can vary widely, and might not be the only thing a class does.


The reason you want an interface is to be able to treat them all alike when commanding them.

Whoever calls walking() (which is a rather odd name btw, it should probably be walk()) is just interested in telling your animal to do just that. The actual implementation will vary but that is not something the caller would care about.


Well, sometimes you'd want to be able to do something to "anything capable of running" without necessarily knowing at design time whether you're talking about a human or a cat or whatever. For instance, imagine a function mammal raceWinner(mammal m1, mammal m2){...} to calculate which mammal would win in a race. To determine who wins, perhaps the function needs to call m1.running() and m2.running(). Of course, the mammals we pass in will really be cats or humans or whatever, and this class supplies the actual implementation of running(). But all raceWinner needs to know is that they have a running() method with the expected signature.

If we only defined running() on cat and human, we couldn't call m1.running() (because the compiler is not guaranteed that m1 has a running() method, as it only knows it's a m1 implements mammal). So instead we'd have to implement a raceWinner(human m1, cat m2) and likewise for two humans, two cats, or any other pair of mammals we had in mind, leading to a lot more work on our part.


An interface provides a contract. It doesn't provide an implementation. It's good practice to interface out your classes.


Of course, walking(), eating() will have different implementation in different animals. But they all walk, run, etc. That is all the interface is saying.


You could model this using inheritance, which would allow you to give default implementations for some or all of the methods. However, interfaces are really useful for declaring a set of features that apply to many unrelated types.

To continue your example, you could imagine a type Alien, which would probably have the same methods, but would not fit in your inheritance hierarchy.


The purpose of interfaces is to tell you what a class does, not how it does it.

This is especially important for accepting things that work differently -- each printer we attach to the PC works differently, so does each scanner, so does each external drive. If all programs needed to care about how each of them worked, you would need to recompile, say, Microsoft Office, for every model of printer that comes out.


One way to develop interfaces is to define an interface and a relative class which implements te interface a common reasonable way. Having both interface and class, you could use the interface in the case the class alreay derives from another class, otherwise a class could derived derivctly to the interface implementation.

It's not always possible, but it solves many problem.

Having a common interface is used to use different object using only the interface (collecting them to a generic list, for example).


There isn't much difference between an entirely abstract class and an interface if you only have one base type. Interfaces can't have any implementation code, but abstract classes can. In this case, abstract classes can be more flexible.

Where interfaces are really useful is that you can assign multiple interfaces to a single implementation, but you can only assign one base class.

for instance, you could have:

class Cat : IMammal, IFourLeggedAnimal
{
}

class Human: IMammal, ITwoLeggedAnimal
{
}

Now you can treat both of them as Mammals, with a "walk()" method, or you can treat them as Four or two legged animals (not necessarily mammals).


What is really useful with an interface like mammal is that you can treat an array of objects (Humans and Cats) as of being of the same type when you want them to walk, eat or run.

For instance if you ware creating a game where you have a number (objects would be created dynamically, but just for example lets say 10 cats and 1 human) of mammals on the screen (saved in a collection), and just wanted them to walk on every turn, you could simply do:

foreach(mammals m in MamalsArrayList){
{
    m.walking();
}

note: I suggest you follow naming conventions and name your interfaces with "I" in front of them, so your example should be named IMammals.

without having to know weather any particular m is either a cat or a human.

Interfaces are hard to show on any particular snippet - but when you really need one you can see how useful they can be.

Of course they have other uses to (that are mentioned in other answers), I just focused on your example.


There are two issues here that are often confused. Inherited behaviour allows different 'commands' to be responded to in the same way e.g Man.walk() === Woman.walk(). Polymorphic behaviour allows the same 'command' to be responded to in different ways e.g. Animal.move() for one object may be different for Animal.move() for another, the bird will choose to fly while the slug will slide.

Now, I would argue the second of these is good while the first is not. Why? Because in OOP we should be encapsulating functionality into objects, which in turn promotes code reuse and all the other nicenesses of OOP. So rather than inheriting behaviour we should delegate it out to a shared object. If you know patterns then this is what State and Strategy are doing.

The problem lies in the fact that normally when you inherit , you get both of these behaviours mixed together. I suggest that this is more trouble than its worth and we should only be using interfaces, though sometimes we do have to make do with whatever the framework provides.

In your specific example Mammal is probably a bad interface name because it doesn't really tell me what it does and it has the potential to blowout to thousands of methods. It's better to divide interfaces into very specific cases. If you were modelling animals you might have a Moveable interface with one method, move(), to which each animal could respond by walking, running, flying, or crawling as appropriate.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜