java 接口编码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1970806/
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-29 18:45:51  来源:igfitidea点击:

Coding to interfaces?

javaoop

提问by Ari

I want to solidify my understanding of the "coding to interface" concept. As I understand it, one creates interfaces to delineate expected functionality, and then implements these "contracts" in concrete classes. To use the interfaceone can simply call the methods on an instance of the concrete class.

我想巩固我对“编码到接口”概念的理解。据我了解,人们创建接口来描述预期的功能,然后在具体的类中实现这些“契约”。要使用接口,可以简单地调用具体类实例上的方法。

The obvious benefit is knowing of the functionality provided by the concrete class, irrespective of its specific implementation.

明显的好处是了解具体类提供的功能,而不管其具体实现如何。

Based on the above:

基于以上:

  1. Are there any fallacies in my understanding of "coding to interfaces"?
  2. Are there any benefits of coding to interfaces that I missed?
  1. 我对“接口编码”的理解有什么谬误吗?
  2. 对我错过的接口进行编码有什么好处吗?

Thanks.

谢谢。

采纳答案by duffymo

Just one possible correction:

只有一种可能的修正:

To use the interface one can simply call the methods on an instance of the concrete class.

要使用接口,可以简单地调用具体类实例上的方法。

One would call the methods on a reference of the type interface, which happens to use the concrete class as implementation:

人们会在类型接口的引用上调用方法,这恰好使用具体类作为实现:

List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");

If you decided to switch to another List implementation, the client code works without change:

如果您决定切换到另一个 List 实现,则客户端代码无需更改即可运行:

List<String> l = new LinkedList<String>();

This is especially useful for hiding implementation details, auto generating proxies, etc.

这对于隐藏实现细节、自动生成代理等特别有用。

You'll find that frameworks like springand guiceencourage programming to an interface. It's the basis for ideas like aspect-orientedprogramming, auto generated proxies for transaction management, etc.

您会发现像springguice这样的框架鼓励对接口进行编程。它是面向方面编程、自动生成的事务管理代理等思想的基础。

回答by JonH

Your understanding seems to be right on. Your co-worker just swung by your desk and has all the latest pics of the christmas party starring your drunk boss loaded onto his thumbdrive. Your co-worker and you do not think twice about how this thumbdrive works, to you its a black box but you know it works because of the USB interface.

你的理解似乎是正确的。你的同事刚刚走过你的办公桌,把你喝醉的老板主演的圣诞派对的所有最新照片都加载到了他的拇指驱动器上。你的同事和你不会三思而后行这个拇指驱动器是如何工作的,对你来说它是一个黑匣子,但你知道它的工作原理是因为USB 接口

It doesn't matter whether it's a SanDisk or a Titanium (not even sure that is a brand), size / color don't matter either. In fact, the only thing that matters is that it is not broken (readable) and that it plugs into USB.

不管它是 SanDisk 还是 Titanium(甚至不确定这是一个品牌),尺寸/颜色也不重要。事实上,唯一重要的是它没有损坏(可读)并且可以插入 USB。

Your USB thumbdrive abides by a contract, it is essentially an interface. One can assume it fulfills some very basic duties:

您的 U 盘遵守约定,它本质上是一个接口。人们可以假设它履行了一些非常基本的职责:

  1. Plugs into USB
  2. Abides by the contract method CopyDataTo:

    public Interface IUSB { void CopyDataTo(string somePath); //used to copy data from the thumbnail drive to... }

  3. Abides by the contract method CopyDataFrom:

    public Interface IUSB { void CopyDataFrom(); //used to copy data from your PC to the thumbnail drive }

  1. 插入 USB
  2. 遵守契约方法CopyDataTo:

    公共接口 IUSB { void CopyDataTo(string somePath); //用于将数据从缩略图驱动器复制到... }

  3. 遵守契约方法CopyDataFrom:

    公共接口 IUSB { void CopyDataFrom(); //用于将数据从您的PC复制到缩略图驱动器}

Ok maybe not those methods but the IUSBinterface is just a contract that the thumbnail drive vendors have to abide by to ensure functionality across various platforms / vendors. So SanDisk makes their thumbdrive by the interface:

好吧,也许不是那些方法,但IUSB接口只是缩略图驱动器供应商必须遵守的合同,以确保跨各种平台/供应商的功能。所以SanDisk通过界面制作了他们的拇指驱动器:

public class SanDiskUSB : IUSB
 {
  //todo: define methods of the interface here
 }

Ari, I think you already have a solid understanding (from what it sounds like) about how interfaces work.

Ari,我认为您已经对接口的工作方式有了深入的了解(从听起来像是这样)。

回答by Michael Borgwardt

To use the interface one can simply call the methods on an instance of the concrete class.

要使用接口,可以简单地调用具体类实例上的方法。

Typically you would have a variable typed to the interface type, thus allowing only access to the methods defined in the interface.

通常,您会将变量类型化为接口类型,从而仅允许访问接口中定义的方法。

The obvious benefit is knowing of the functionality provided by the concrete class, irrespective of its specific implementation.

明显的好处是了解具体类提供的功能,而不管其具体实现如何。

Sort of. Most importantly, it allows you to write APIs that take parameters with interface types. Users of the API can then pass in their own classes (which implement those interfaces) and you code will work on those classes even though they didn't exist yet when it was written (such as java.util.Arrays.sort() being able to sort anything that implements Comparableor comes with a suitable Comparator).

有点。最重要的是,它允许您编写带有接口类型参数的 API。API 的用户然后可以传入他们自己的类(实现这些接口),您的代码将在这些类上工作,即使它们在编写时还不存在(例如 java.util.Arrays.sort()能够对实现Comparable或带有合适的任何东西进行排序Comparator)。

From a design perspective, interfaces allow/enforce a clear separation between API contracts and implementation details.

从设计的角度来看,接口允许/强制执行 API 契约和实现细节之间的明确分离。

回答by Paul Creasey

The main advantage is that the use of an interface loosely couplesa class with it's dependencies. You can then change a class, or implement a new concrete interface implementation without ever having to change the classes which depend on it.

主要优点是接口的使用将类与其依赖项松散耦合。然后,您可以更改一个类,或实现一个新的具体接口实现,而无需更改依赖于它的类。

回答by meriton

The aim of coding against interfaces is to decouple your code from the concrete implementation in use. That is, your code will not make assumptions about the concrete type, only the interface. Consequently, the concrete implementation can be exchanged without needing to adjust your code.

针对接口编码的目的是将您的代码与正在使用的具体实现分离。也就是说,您的代码不会对具体类型做出假设,只会对接口做出假设。因此,无需调整代码即可交换具体实现。

回答by Nathan Hughes

You didn't list the part about how you get an implementation of the interface, which is important. If you explicitly instantiate the implementing class with a constructor then your code is tied to that implementation. You can use a factory to get an instance for you but then you're as tied to the factory as you were before to the implementing class. Your third alternative is to use dependency injection, which is having a factory plug the implementing object into the object that uses it, in which case you escape having the class that uses the object being tied to the implementing class or to a factory.

您没有列出有关如何获得接口实现的部分,这很重要。如果您使用构造函数显式实例化实现类,那么您的代码将绑定到该实现。您可以使用工厂为您获取一个实例,但是您会像以前一样与工厂绑定到实现类。您的第三种选择是使用依赖注入,即让工厂将实现对象插入到使用它的对象中,在这种情况下,您可以避免将使用对象的类绑定到实现类或工厂。

回答by bkildow

I think you may have hinted at this, but I believe one of the biggest benefits of coding to an interface is that you are breaking dependency on concrete implementation. You can achieve loose coupling and make it easier to switch out specific implementations without changing much code. If you are just learning, I would take a look at various design patternsand how they solve problems by coding to interfaces. Reading the book Head First: Design Patternsreally helped things click for me.

我想您可能已经暗示过这一点,但我相信对接口进行编码的最大好处之一是您打破了对具体实现的依赖。您可以实现松散耦合,并在不更改大量代码的情况下更轻松地切换特定实现。如果你只是在学习,我会看看各种设计模式以及它们如何通过编码到接口来解决问题。阅读《Head First: Design Patterns》这本书对我来说真的很有帮助。

回答by Shaun F

As I understand it, one creates interfaces to delineate expected functionality, and then implements these "contracts" in concrete classes.

据我了解,人们创建接口来描述预期的功能,然后在具体的类中实现这些“契约”。

The only sort of mutation i see in your thinking is this - You're going to call out expected contracts, not expected functionality. The functionality is implemented in the concrete classes. The interface only states that you will be able to call something that implements the interface with the expected method signatures. Functionality is hidden from the calling object.

我在您的想法中看到的唯一变化是 - 您将调用预期的合同,而不是预期的功能。该功能在具体类中实现。该接口仅声明您将能够调用实现具有预期方法签名的接口的东西。功能对调用对象是隐藏的。

This will allow you to stretch your thinking into polymorphism as follows.

这将允许您将您的想法扩展为如下所示的多态性。

SoundMaker sm = new Duck();<br/>
SoundMaker sm1 = new ThunderousCloud();

sm.makeSound(); // quack, calls all sorts of stuff like larynx, etc.<br/>
sm1.makeSound(); // BOOM!, completely different operations here...