简体   繁体   中英

why ambiguity happens in multiple inheritance not in interfaces

How can we achieve ambiguity in interfaces? Can't we achieve ambiguity using abstract classes? I think abstract classes can also collection of fully abstract methods. Then why do we need interfaces.

A fully abstract class and an interface appear the same on the surface, but they are very different when initiating. Take the following:

public interface WildAnimal { ... }
public interface TamePet { ... }
public class Dog implements WildAnimal, TamePet { ... }

abstract class BadWildAnimal { ... } // fully abstract
abstract class BadTamePet extends BadWildAnimal{ ... } // fully abstract 
public abstract class BadDog extends BadTamePet { ... } // defines all methods of both BadAnimal and BadPet

In my code I have a Dog. This Dog can be treated wild or tame and I can pass it to and from methods as such:

WildAnimal myDog = new Dog(); // I will treat this object as though it is a wild animal
TamePet trainedDog = trainMyDog(myDog); // I will treat this object as though it is a trained pet

protected Dog trainMyDog(Dog someDog) { ... }

What I have said here is that I started out with a WildAnimal (in this case, it was a dog), and I trained the dog so that now it is a TamePet. The trainMyDog(Dog someDog) method only knows that it will be getting a dog. It will do something to it and then give back a dog. The caller knows that it will give it a dog which was a WildAnimal and will get back a TamePet .

The important thing to know here is that the myDog object could only see and have access to the methods that are defined in WildAnimal . the trainedDog object could only see and have access to the methods that are defined in TamePet . Even though Dog implements both, those objects can only act on those methods that the interface defines which they are defined as. These objects are not of class Dog . They are of type WildAnimal and TameDog respectively.

If we had done this the other way then our code reads completely different. There is only one class we can initiate and that is class BadDog . It is both a BadWildAnimal class and a BadTamePet at the same time, which doesn't make logical sense.

The code looks weird as well:

BadDog myDog = new BadDog();
BadDog trainedDog = trainMyDog(BadDog someDog);

protected BadDog trainMyDog(BadDog someDog) { ... }

If someone else comes later on to read your code, or if you go back years later to update your code, this code above makes no sense. You can try typecasting, but then it gets even harder to read and passing the objects becomes a chore. If you use interfaces, however, it is quite obvious what was happening and how it was being done.

In these examples, interfaces make the code easier to read and insure that I am using the object correctly. There may be a method in the Dog class that is called biteTheMailman() , but if that is defined in the WildAnimal interface, then ONLY the myDog object can do that. I won't be able to have my trainedDog do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM