java 接口的目的(续)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4052621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:35:02  来源:igfitidea点击:

The purpose of interfaces continued

javaoopinterface

提问by Julio

OK so I gather that Interfaces are a way to enforce that an object implements a certain amount of functionality, without having to use inheritance. Kind of like a contract. And I semi see the point of them.

好的,所以我认为接口是一种强制对象实现一定数量功能的方法,而不必使用继承。有点像合同。我半明白他们的意思。

But if all you have in the interface is:

但是,如果您在界面中拥有的只是:

 public interface animal{
  void eat(object food);
}

and it has no implementation as such, then whoever uses your interface has to write it from scratch, every time.

并且它没有这样的实现,那么使用你的接口的人每次都必须从头开始编写它。

If you are creating a number of classes all implementing such features and the implementation is only slightly different, this is going to be a lot of hard work.

如果您正在创建许多都实现这些功能的类,并且实现只是略有不同,这将是一项艰巨的工作。

Any help to get my head around this is appreciated because I know it's really important.

感谢您帮助我解决这个问题,因为我知道这非常重要。

回答by Andrei Fierbinteanu

Interfaces are the only way to create multiple inheritance in Java.

接口是在 Java 中创建多重继承的唯一方法。

Say you create a class Animal. And all animals, including humans extend that. And each of those animals inherits common methods like eat, breathe, etc.

假设您创建了一个类Animal。包括人类在内的所有动物都扩展了这一点。这些动物中的每一种都继承了常见的方法,例如进食、呼吸等。

But now let's say you have a MathProblemclass. And you want to have certain classes that can solve that problem by passing the problem to a solve(MathProblem problem)method. And you know that a Human, but also a Computermight solve the math problem. So they both need to be able to solve that problem. You might be able to get the Computer to extend some MathSolverclass that has the method, but Human already extends Animal, and can't extends anything else. So a better way is to make MathSolver an interface and have both Human, Computer, and any other classes that need to solve problems implement that.

但是现在假设您有一MathProblem堂课。并且您希望某些类可以通过将问题传递给solve(MathProblem problem)方法来解决该问题。而且您知道 a Human,但也 aComputer可能会解决数学问题。所以他们都需要能够解决这个问题。您也许可以让 Computer 扩展一些MathSolver具有该方法的类,但是 Human 已经扩展了 Animal,并且不能扩展任何其他类。所以,更好的办法是让MathSolver的接口,并同时拥有HumanComputer以及其他任何类,需要解决的问题,实现一个。

Also note that a Humanand a Computermight solve the problems in completely different ways, since their such different objects. That's what interfaces are best for. Defining certain abilities that cut across multiple inheritance hierarchies, and can have very different implementations, but can all be passed to a method that accepts any of them. Think of the Comparableinterface; it's not something a certain class of objects has, all sort of things can be compared, and usually in very different ways. But you can always call sort on a Listof Comparableobjects since you know they have a certain order, no matter if they're Numbers, Animals, Computersor anything else (as long as they implement Comparableand define their ordering).

另请注意, aHuman和 aComputer可能以完全不同的方式解决问题,因为它们的对象不同。这就是接口最适合的地方。定义某些跨越多个继承层次结构的能力,可以有非常不同的实现,但都可以传递给接受其中任何一个的方法。想想Comparable界面;它不是某类对象所具有的东西,所有类型的东西都可以进行比较,并且通常以非常不同的方式进行比较。但是,你可以随时调用排序上ListComparable对象,因为你知道他们有一定的顺序,不管他们是NumbersAnimalsComputers或其他任何东西(只要它们实现Comparable并定义它们的顺序)。

回答by Carl Manaster

Prefer Composition over Inheritance.This way, you can implement (say) eat() in a class that gets incorporated into all your animals as a data member. Write it once, reuse it, but in a way that doesn't bind one kind of functionality explicitly to another.

更喜欢组合而不是继承。通过这种方式,您可以在一个类中实现(比如)eat(),该类作为数据成员并入您的所有动物。编写一次,重用它,但不会将一种功能显式绑定到另一种功能。

If you had two (or ten) different ways of eating, you could swap them out as needed.

如果您有两种(或十种)不同的饮食方式,您可以根据需要更换它们。

回答by Petar Minchev

You are confusing interfaces and inheritance. They are different concepts and can complement to each other. If all the eat methods are only slightly different, then you can create a base class which will contain the common code and will be invoked from the subclasses through overriden methods which add the different parts. The base class can still implement the interface. Hope it is clear.

你混淆了接口和继承。它们是不同的概念,可以相互补充。如果所有的eat 方法只是略有不同,那么您可以创建一个包含公共代码的基类,并将通过添加不同部分的覆盖方法从子类中调用。基类仍然可以实现接口。希望它很清楚。

回答by user45492

Right, you need to implement it ever time but you can implement it differently every time and any class that calls it doesn't need to worry about how it's implemented.

是的,您需要每次都实现它,但是您可以每次都以不同的方式实现它,任何调用它的类都不需要担心它是如何实现的。

For example, if you have a Zoo object with a bunch of animals (new Tiger(), Lion(), Bear()) then your zoo can do for each Animal a in some collection a.eat() and it will work. The zoo doesn't care that there are three different types of animals that eat in totally different ways.

例如,如果您有一个包含一堆动物(new Tiger()、Lion()、Bear())的 Zoo 对象,那么您的动物园可以对某个集合 a.eat() 中的每个 Animal a 执行操作,并且它会起作用。动物园并不关心三种不同类型的动物以完全不同的方式进食。

回答by Hyman

If you are creating a number of classes all implementing such features and the implementation is only slightly different, this is going to be a lot of hard work.

如果您正在创建许多都实现这些功能的类,并且实现只是略有不同,这将是一项艰巨的工作。

In that case you are easily allowed to create another layer in you hierarchy of classes which implements Animalbut is an ancestor class for all animals that eat in some way, for example

在这种情况下,您可以轻松地在您的类层次结构中创建另一个层,该层实现Animal但是以某种方式进食的所有动物的祖先类,例如

class Herbivore implements Animal {
  public void eat(Object food) {
   ...
  }
}

class Cow extends Herbivore..
class Horse extends Herbivore..

and you are allowed to override eatby using super.eat()and changing only the slight part..

并且您可以eat通过super.eat()仅使用和更改轻微的部分来覆盖..

You should look forward code reuse and encapsulation of components at the same time.. then if your interface really doesn't characterize the class itself but just a component of it you can go by composition as suggested by Carl Manaster.

您应该同时期待代码重用和组件封装.. 那么如果您的界面真的没有表征类本身而只是它的一个组件,您可以按照 Carl Manaster 的建议进行组合。

回答by Thomas Weller

You should think of an interface as an authoritative declaration of behaviour, which has nothing to do with implementation issues in the first place.

您应该将接口视为行为的权威声明,这首先与实现问题无关。

If you want to avoid code duplication, then you use an abstract base class in combination with the interface. Here you then can implement all the stuff that might be repeated in all interface-implementing classes otherwise.

如果您想避免代码重复,那么您可以将抽象基类与接口结合使用。然后,您可以在这里实现所有可能在所有接口实现类中重复的内容。

HTH.
Thomas

哈。
托马斯

回答by Marcus

And old thread, I know. But I just read "Interfaces are the only way to create multiple inheritance in Java". This is very wrong, because delegation (or "compositon" as Carl said) is the only way to get multiple inheritance (remember: "delegation is inheritance", well, almost).

和旧线程,我知道。但我刚刚读到“接口是在 Java 中创建多重继承的唯一方法”。这是非常错误的,因为委托(或卡尔所说的“组合”)是获得多重继承的唯一方法(记住:“委托就是继承”,好吧,几乎)。

You only need interfaces to tell the developer "hey, don't forget to delegate this or that class"! Interfaces are only needed as reminder for a correct delegation (or in general: implementation), but they can't inherite any code. With multiple inheritance interfaces wouldn't be needed at all.

你只需要接口告诉开发人员“嘿,不要忘记委托这个或那个类”!接口只需要作为正确委托(或一般:实现)的提醒,但它们不能继承任何代码。根本不需要多继承接口。

Actually, you don't really need interfaces to create a working program, they're just helpers without any function or functional code. Btw Thomas was very right with the abstract classes, these are far more important than interfaces, because that's where you can get reusable code from.

实际上,您并不真正需要接口来创建工作程序,它们只是没有任何功能或功能代码的助手。顺便说一句,Thomas 对抽象类的看法非常正确,它们比接口重要得多,因为您可以从中获得可重用的代码。

Normally, when I write a java application I only create interfaces in the very end, as a helper for future programmers. Or I don't create any interfaces at all ;D

通常,当我编写 Java 应用程序时,我只在最后创建接口,作为未来程序员的帮手。或者我根本不创建任何接口;D

回答by Milk Man

One major reason is that you can create an object using an interface reference, similar to an abstract method. When you do this, every object which implements the interface can be assigned to it. For example, if Dog and Car both implement Washable, then you can do:

一个主要原因是您可以使用接口引用创建对象,类似于抽象方法。当你这样做时,实现接口的每个对象都可以分配给它。例如,如果 Dog 和 Car 都实现了 Washable,那么您可以执行以下操作:

Washable wD=new Dog();

可水洗 wD=new Dog();

Washable wC=new Car();

可水洗 wC=new Car();

If Washable has the public abstract method wash(), then you can do this:

如果 Washable 有公共抽象方法wash(),那么你可以这样做:

wD.wash();

wD.wash();

wC.wash();

wC.wash();

and their respective methods will be called. This also means that you can accept an interface as a parameter for a method meaning you don't have to add unecessary code to deal with every class which implements a certain interface.

并且它们各自的方法将被调用。这也意味着您可以接受一个接口作为方法的参数,这意味着您不必添加不必要的代码来处理实现某个接口的每个类。

See here for a more detailed explanation: http://www.artima.com/objectsandjava/webuscript/PolymorphismInterfaces1.html

有关更详细的解释,请参见此处:http: //www.artima.com/objectsandjava/webuscript/PolymorphismInterfaces1.html

回答by Manish Bannur

Generalization

概括

Using JAVA Interface we can achieve generalization across sub-class. The generalization means here sub-classes having same behavior implemented in a different way.

使用 JAVA 接口,我们可以实现跨子类的泛化。泛化在这里意味着具有以不同方式实现的相同行为的子类。

Standardization

标准化

Interface allows to set standardization for all the sub-classes which implements it. It specifies "what" the sub-classes must have but doesn't enforce how it should have.

接口允许为实现它的所有子类设置标准化。它指定子类必须具有的“什么”,但不强制它应该如何具有。

100 % Abstraction

100% 抽象

Interface body provides 100% abstraction, so that the sub-class should not miss any implementation of abstract method. This isn't possible if we use abstract classes.

接口体提供100%抽象,子类不会遗漏任何抽象方法的实现。如果我们使用抽象类,这是不可能的。

De-Coupling(Loose Coupling)

解耦(松耦合)

While developing an application, the code which interacts with end users can be loosely coupled to the code running on the server[B L C] by using interfaces.

在开发应用程序时,与最终用户交互的代码可以通过接口与运行在服务器上的代码松散耦合[BLC]。

Multiple Inheritance

多重继承

Using interfaces we can achieve MI which is not possible using classes.

使用接口我们可以实现使用类无法实现的 MI。

回答by Wes P

Using interfaces is more about giving the consuming code a way to know what you expect from it, rather than you needing to be concerned about the details of the consuming code.

使用接口更多的是让消费代码知道你对它的期望,而不是你需要关心消费代码的细节。

For example, one of the ways we use interfaces a lot is in our Business Layer / Data Access Layer.

例如,我们经常使用接口的方式之一是在我们的业务层/数据访问层。

Because our business layer (BL) assembly will communicate with directly with the data access layer (DAL) assembly, the DAL cannot communicate directly with the BL. What happens if the DAL wants to use objects rather than individual fields? You would have to define your own DAL objects, and hydrate them with the input you've just received. Basically, a lot more work, more resources consumed, and multiple objects that represent the same data which makes for a maintenance nightmare.

由于我们的业务层 (BL) 程序集将直接与数据访问层 (DAL) 程序集通信,因此 DAL 无法直接与 BL 通信。如果 DAL 想要使用对象而不是单个字段,会发生什么情况?您必须定义自己的 DAL 对象,并使用您刚刚收到的输入将它们混合。基本上,更多的工作、更多的资源消耗以及代表相同数据的多个对象,这使得维护噩梦。

But, if you define interfaces in the DAL, you can tell consumers of the DAL what it expects. Then you can implement those interfaces in the BL and pass instances of the interfaces instead of BL objects.

但是,如果您在 DAL 中定义接口,您可以告诉 DAL 的使用者它期望什么。然后您可以在 BL 中实现这些接口并传递接口的实例而不是 BL 对象。

Interfaces are all about abstracting out the details of the implementation where they're not absolutely necessary.

接口都是关于在它们不是绝对必要的地方抽象出实现的细节。

[Edit] If you have a lot of objects that do similar things, a combination of an interface and a base class with overridable/virtual methods might be more useful than just an interface.

[编辑] 如果你有很多做类似事情的对象,一个接口和一个基类与可重写/虚拟方法的组合可能比仅仅一个接口更有用。