“编程到接口”是什么意思?

自闭症网瘾萝莉.ら 提交于 2019-12-19 17:07:49

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

我已经看过几次这个问题了,我不清楚它是什么意思。 您何时以及为什么要这样做?

我知道接口的作用,但是我对此不清楚,这使我觉得我错过了正确使用它们的机会。

如果要这样做,是否只是这样:

IInterface classRef = new ObjectWhatever()

您可以使用实现IInterface任何类吗? 您什么时候需要这样做? 我唯一能想到的是,如果您有一个方法,并且不确定要实现IInterface对象,则不确定该对象将被传递。 我不认为您需要多久这样做一次。

另外,您如何编写一个接受实现接口的对象的方法? 那可能吗?


#1楼

接口的编程与Java或.NET中的抽象接口绝对无关。 它甚至不是OOP概念。

这意味着不要搞乱对象或数据结构的内部。 使用抽象程序接口或API与您的数据进行交互。 在Java或C#中,这意味着使用公共属性和方法而不是原始字段访问。 对于C,这意味着使用函数而不是原始指针。

编辑:对于数据库,这意味着使用视图和存储过程,而不是直接表访问。


#2楼

C ++解释。

将接口视为类的公共方法。

然后,您可以创建一个“依赖”这些公共方法的模板,以执行其自己的功能(它使在类的公共接口中定义的函数调用)。 可以说,此模板是一个容器,例如Vector类,并且它依赖的接口是搜索算法。

定义函数/接口Vector进行调用的任何算法类都将满足“合同”(如原始答复中所解释的)。 这些算法甚至不必是相同的基类。 唯一的要求是在算法中定义Vector依赖的函数/方法(接口)。

所有这些的目的是,您可以提供任何不同的搜索算法/类,只要它提供了Vector依赖的接口(气泡搜索,顺序搜索,快速搜索)即可。

您可能还需要设计其他容器(列表,队列),这些容器可以通过使它们满足您的搜索算法所依赖的接口/合同来利用与Vector相同的搜索算法。

这样可以节省时间(OOP原则“代码重用”),因为您能够针对创建的每个新对象编写一次而不是一次又一次地编写算法,而不会因过度使用继承树而使问题复杂化。

至于“错过”事情如何运作; 大型应用程序(至少在C ++中),因为这是大多数标准TEMPLATE库框架的工作方式。

当然,当使用继承和抽象类时,对接口进行编程的方法会发生变化。 但是原理是一样的,您的公共函数/方法是您的类接口。

这是一个巨大的主题,也是“设计模式”的基石原则之一。


#3楼

那里有很多解释,但要使其更加简单。 以List为例。 可以使用以下方式实现列表:

  1. 内部数组
  2. 链表
  3. 其他实施

通过构建接口,说一个List 。 您只需要编码List的定义或List实际上的含义。

您可以在内部使用任何类型的实现,例如array实现。 但是假设您出于某种原因(例如错误或性能)而希望更改实现。 然后,您只需要将声明List<String> ls = new ArrayList<String>()更改为List<String> ls = new LinkedList<String>()

代码中没有其他地方,您是否需要更改其他任何内容? 因为其他所有内容都基于List的定义。


#4楼

问:-...“您能使用任何实现接口的类吗?”
答:是的。

问:-...“您什么时候需要这样做?”
答:-每次需要一个实现接口的类。

注意: 我们无法实例化类未实现的接口 -True。

  • 为什么?
  • 因为该接口仅具有方法原型,而没有定义(仅是函数名称,而不是其逻辑)

AnIntf anInst = new Aclass();
// 仅当 Aclass实现AnIntf​​时,我们才能这样做。
// anInst将具有Aclass引用。


注意: 现在我们可以理解,如果Bclass和Cclass实现相同的Dintf,会发生什么。

Dintf bInst = new Bclass();  
// now we could call all Dintf functions implemented (defined) in Bclass.

Dintf cInst = new Cclass();  
// now we could call all Dintf functions implemented (defined) in Cclass.

我们所拥有的:相同的接口原型(接口中的函数名称),并调用不同的实现。

参考书目: 原型-维基百科


#5楼

短篇小说:要求邮递员回家后回家,并接收包含其上写有地址的封面(信件,文件,支票,礼品卡,申请书,情书)。

假设没有掩护,请邮递员回家后收拾所有东西并交付给其他人,邮递员会感到困惑。

所以最好用封面包好(在我们的故事中是界面),然后他会做得很好。

现在,邮递员的工作是仅接收和交付封面(他不会打扰封面中的内容)。

创建不是实际类型的interface类型,而是使用实际类型实现它。

创建接口意味着您的组件可以轻松适应其余代码

我举一个例子。

您具有如下的AirPlane界面。

interface Airplane{
    parkPlane();
    servicePlane();
}

假设您的飞机控制器类中有一些方法,例如

parkPlane(Airplane plane)

servicePlane(Airplane plane)

在您的程序中实现。 它不会破坏您的代码。 我的意思是,只要接受像AirPlane这样的参数,就不需要更改。

因为它将接受任何飞机,而不管实际的类型, flyer ,高highflyrfighter等。

另外,在集合中:

List<Airplane> plane; //将搭乘您的所有飞机。

以下示例将清除您的理解。


你有一架实施它的战斗机,所以

public class Fighter implements Airplane {

    public void  parkPlane(){
        // Specific implementations for fighter plane to park
    }
    public void  servicePlane(){
        // Specific implementatoins for fighter plane to service.
    }
}

HighFlyer和其他事件也是如此:

public class HighFlyer implements Airplane {

    public void  parkPlane(){
        // Specific implementations for HighFlyer plane to park
    }

    public void  servicePlane(){
        // specific implementatoins for HighFlyer plane to service.
    }
}

现在考虑使用AirPlane几次您的控制器类,

假设您的Controller类是ControlPlane,如下所示,

public Class ControlPlane{ 
 AirPlane plane;
 // so much method with AirPlane reference are used here...
}

神奇之处在于,您可以使新的AirPlane类型实例达到所需的数量,并且无需更改ControlPlane类的代码。

您可以添加一个实例...

JumboJetPlane // implementing AirPlane interface.
AirBus        // implementing AirPlane interface.

您也可以删除以前创建的类型的实例。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!