简体   繁体   English

为什么在多重继承而不是在接口中发生歧义

[英]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. 我在这里说的是,我是从WildAnimal (在这种情况下,它是一只狗)开始的,我训练了这只狗,现在它变成了TamePet。 The trainMyDog(Dog someDog) method only knows that it will be getting a dog. trainMyDog(Dog someDog)方法只知道它将trainMyDog(Dog someDog)狗。 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 . 呼叫者知道它将给它一只WildAnimal狗,并且会收回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 . 在这里要知道的重要一点是, myDog对象只能查看和访问WildAnimal中定义的方法。 the trainedDog object could only see and have access to the methods that are defined in TamePet . trainedDog对象只能看到并有权访问TamePet中定义的方法。 Even though Dog implements both, those objects can only act on those methods that the interface defines which they are defined as. 即使Dog实现了这两种方法,这些对象也只能对接口定义它们所定义的方法起作用。 These objects are not of class Dog . 这些对象不是Dog类的。 They are of type WildAnimal and TameDog respectively. 它们分别是WildAnimalTameDog类型。

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 . 我们只能启动一个类,即BadDog类。 It is both a BadWildAnimal class and a BadTamePet at the same time, which doesn't make logical sense. 它既是BadWildAnimal类和BadTamePet的同时,不使逻辑意义。

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. Dog类中可能有一个名为biteTheMailman() ,但是如果在WildAnimal接口中定义了该WildAnimal ,则只有myDog对象可以做到这一点。 I won't be able to have my trainedDog do that. 我将无法让我trainedDog做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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