Welcome to JavaRanch!
Maybe an example would help.
Suppose you have a class called Veterinarian. An instance of Veterinarian will most likely
do things with animals. In other words, it will probably have methods that take different kinds of animals as parameters. One way to do this is to overload
each method for
each kind of animal...
void examine(Cat c) {...}
void examine(Dog d) {...}
void examine(Ferret f) {...}
//etc.
But as you can see, this will require a different method for each kind of animal. And whenever a new type of animal is introduced, the Veterinarian class will need to be modified.
An alternative approach is to define an interface called Animal, that all types of animals would implement. Then a Cat IS-AN Animal, a Dog IS-AN Animal, and so on. Now, all the Veterinarian class needs is
one version of each method...
void examine(Animal a) {...}
Not only does this eliminate the need for multiple overloaded versions, but it also means that the Veterinarian class does
not need any modifications when new types of Animals are introduced.
Note that this is closely tied to another important principle:
Polymorphism. If we have an Animal a, and we call a.makeSound(); this will invoke the method body of the Animal's
true runtime type. For example, if a is really a Cat, it will invoke the Cat's makeSound implementation. On the other hand, if a is a Dog, then calling a.makeSound() will invoke the Dog's makeSound implementation.
[ January 20, 2007: Message edited by: marc weber ]