Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【原】【JavaSE】接口的概念 #31

Open
vagabond1-1983 opened this issue Feb 14, 2016 · 0 comments
Open

【原】【JavaSE】接口的概念 #31

vagabond1-1983 opened this issue Feb 14, 2016 · 0 comments

Comments

@vagabond1-1983
Copy link
Owner

接口就是为了规范某种行为所做的约定。
举个例子就是,USB接口。想象一下,如果手机想跟电脑传输数据,他们又分属于不同的厂商,怎么样规定才能协同工作呢?肯定不能先做好手机,把手机拿到电脑厂商那,电脑厂商根据这个规范,再生产电脑。这样毫无效率可言。那是不是可以先定义好要怎么连接,有多少针脚,都是什么样的。然后把规范给手机厂商和电脑厂商,他们根据这个规范把接口留出来。USB就是一个接口。定义好了USB这个模式之后,手机厂商和电脑厂商可以独自的去生产自己的设备,只需遵循规范留出一个接口,将来就能相互通信了。手机上有USB接口,电脑上用USB接口。这就是接口的作用。
同样的道理,软件设计也是这样。不同系统之间相互通信,也是靠预先定义好的接口通信。这样的耦合度低。系统内部也是这样的设计才够灵活。

知乎上有这样的一个问题:
Java 中的接口有什么作用?
例如我定义了一个接口,但是我在继承这个接口的类中还要写接口的实现方法,那我不如直接就在这个类中写实现方法岂不是更便捷,还省去了定义接口?接口在java中的作用是什么?个人觉得只是一种规范。大家的看法呢?

有一个回答是这样的:
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Dion
链接:http://www.zhihu.com/question/20111251/answer/14012223
来源:知乎
“接口是个规范”,这句没错。“不如直接就在这个类中写实现方法岂不是更便捷”,你怎么保证这个接口就一个类去实现呢?如果多个类去实现同一个接口,程序怎么知道他们是有关联的呢?既然不是一个类去实现,那就是有很多地方有用到,大家需要统一标准。甚至有的编程语言(Object-C)已经不把接口叫 interface,直接叫 protocol。统一标准的目的,是大家都知道这个是做什么的,但是具体不用知道具体怎么做。比如说:我知道 Comparable 这个接口是用来比较两个对象的,那么如何去比较呢?数字有数字的比较方法,字符串有字符串的比较方法,学生(自己定义的类)也有自己的比较方法。然后,在另外一个负责对象排序(不一定是数字喔)的代码里面,肯定需要将两个对象比较。这两个对象是什么类型呢?Object a,b?肯定不行,a > b 这样的语法无法通过编译。int a,b?也不行?一开始就说了,不一定是数字。....所以,Comparable 就来了。他告诉编译器,a b 两个对象都满足 Comparable 接口,也就是他们是可以进行比较的。具体怎么比较,这段程序不需要知道。所以,他需要一些具体的实现,Comparable 接口有一个方法,叫 compareTo。那么这个方法就是用来取代 <、> 这样的运算符。因为运算符是编译器保留给内置类型(整数、浮点数)进行比较用的,而不是一个广义的比较运算。如果你可以明白 JDK 自身库里面诸如 Comparable 这样已经有的接口,那么就很容易理解自己在开发程序的时候为什么需要用到接口了。

我比较赞同。另外在java中,接口还有一个作用就是支持多继承。
我们都知道java不像c++一样,支持多继承,而通过接口的方式,java可以实现多个接口,从而间接的支持多继承。
还有一个问题,抽象类跟接口有什么区别?什么时候该用抽象类?什么时候该用接口?
我的理解是抽象类是一个具体的事物,而接口是行为的规范。
从网上找到下面的解释,我觉得还是比较到位的。贴出来收藏下。
http://www.cnblogs.com/dolphin0520/p/3811437.html
1.语法层面上的区别

  1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

  2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

  4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2.设计层面上的区别

  1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。

  2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

  下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:

abstract class Door {
    public abstract void open();
    public abstract void close();
}

或者

interface Door {
    public void open();
    public void close;
}

但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:

  1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;

  2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。

  从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。

interface Alarm {
    void alarm();
}

abstract class Door {
    void open();
    void close();
}

class AlarmDoor extends Door implements Alarm {
    void open() {...}
    void close() {...}
    void alarm() {...}
}
@vagabond1-1983 vagabond1-1983 changed the title 【JavaSE】接口的概念 【原】【JavaSE】接口的概念 Feb 14, 2016
@vagabond1-1983 vagabond1-1983 added this to the Java语言 milestone Feb 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant