当前位置:  技术问答>java相关

请问,接口与抽象类之间有何区别

    来源: 互联网  发布时间:2015-06-09

    本文导语:  小妹初学java,有些概念不清。 请问,接口与抽象类之间有何区别,最好能说的规范(书面化)一点,谢谢。 | 7.4 抽象类和方法 在我们所有乐器(Instrument)例子中,基础类Instrument内的方法都肯定是“...

小妹初学java,有些概念不清。
请问,接口与抽象类之间有何区别,最好能说的规范(书面化)一点,谢谢。

|
7.4 抽象类和方法
在我们所有乐器(Instrument)例子中,基础类Instrument内的方法都肯定是“伪”方法。若去调用这些方法,就会出现错误。那是由于Instrument的意图是为从它衍生出去的所有类都创建一个通用接口。
之所以要建立这个通用接口,唯一的原因就是它能为不同的子类型作出不同的表示。它为我们建立了一种基本形式,使我们能定义在所有衍生类里“通用”的一些东西。为阐述这个观念,另一个方法是把Instrument称为“抽象基础类”(简称“抽象类”)。若想通过该通用接口处理一系列类,就需要创建一个抽象类。对所有与基础类声明的签名相符的衍生类方法,都可以通过动态绑定机制进行调用(然而,正如上一节指出的那样,如果方法名与基础类相同,但自变量或参数不同,就会出现过载现象,那或许并非我们所愿意的)。
如果有一个象Instrument那样的抽象类,那个类的对象几乎肯定没有什么意义。换言之,Instrument的作用仅仅是表达接口,而不是表达一些具体的实施细节。所以创建一个Instrument对象是没有意义的,而且我们通常都应禁止用户那样做。为达到这个目的,可令Instrument内的所有方法都显示出错消息。但这样做会延迟信息到运行期,并要求在用户那一面进行彻底、可靠的测试。无论如何,最好的方法都是在编译期间捕捉到问题。
针对这个问题,Java专门提供了一种机制,名为“抽象方法”。它属于一种不完整的方法,只含有一个声明,没有方法主体。下面是抽象方法声明时采用的语法:
abstract void X();
包含了抽象方法的一个类叫作“抽象类”。如果一个类里包含了一个或多个抽象方法,类就必须指定成abstract(抽象)。否则,编译器会向我们报告一条出错消息。
若一个抽象类是不完整的,那么一旦有人试图生成那个类的一个对象,编译器又会采取什么行动呢?由于不能安全地为一个抽象类创建属于它的对象,所以会从编译器那里获得一条出错提示。通过这种方法,编译器可保证抽象类的“纯洁性”,我们不必担心会误用它。
如果从一个抽象类继承,而且想生成新类型的一个对象,就必须为基础类中的所有抽象方法提供方法定义。如果不这样做(完全可以选择不做),则衍生类也会是抽象的,而且编译器会强迫我们用abstract关键字标志那个类的“抽象”本质。
即使不包括任何abstract方法,亦可将一个类声明成“抽象类”。如果一个类没必要拥有任何抽象方法,而且我们想禁止那个类的所有实例,这种能力就会显得非常有用。
Instrument类可很轻松地转换成一个抽象类。只有其中一部分方法会变成抽象方法,因为使一个类抽象以后,并不会强迫我们将它的所有方法都同时变成抽象。下面是它看起来的样子:

266页图

下面是我们修改过的“管弦”乐器例子,其中采用了抽象类以及方法:

266-268页程序

可以看出,除基础类以外,实际并没有进行什么改变。
创建抽象类和方法有时对我们非常有用,因为它们使一个类的抽象变成明显的事实,可明确告诉用户和编译器自己打算如何用它。

7.5 接口
“interface”(接口)关键字使抽象的概念更深入了一层。我们可将其想象为一个“纯”抽象类。它允许创建者规定一个类的基本形式:方法名、自变量列表以及返回类型,但不规定方法主体。接口也包含了基本数据类型的数据成员,但它们都默认为static和final。接口只提供一种形式,并不提供实施的细节。
接口这样描述自己:“对于实现我的所有类,看起来都应该象我现在这个样子”。因此,采用了一个特定接口的所有代码都知道对于那个接口可能会调用什么方法。这便是接口的全部含义。所以我们常把接口用于建立类和类之间的一个“协议”。有些面向对象的程序设计语言采用了一个名为“protocol”(协议)的关键字,它做的便是与接口相同的事情。
为创建一个接口,请使用interface关键字,而不要用class。与类相似,我们可在interface关键字的前面增加一个public关键字(但只有接口定义于同名的一个文件内);或者将其省略,营造一种“友好的”状态。
为了生成与一个特定的接口(或一组接口)相符的类,要使用implements(实现)关键字。我们要表达的意思是“接口看起来就象那个样子,这儿是它具体的工作细节”。除这些之外,我们其他的工作都与继承极为相似。下面是乐器例子的示意图:

269页图

具体实现了一个接口以后,就获得了一个普通的类,可用标准方式对其进行扩展。
可决定将一个接口中的方法声明明确定义为“public”。但即便不明确定义,它们也会默认为public。所以在实现一个接口的时候,来自接口的方法必须定义成public。否则的话,它们会默认为“友好的”,而且会限制我们在继承过程中对一个方法的访问——Java编译器不允许我们那样做。
在Instrument例子的修改版本中,大家可明确地看出这一点。注意接口中的每个方法都严格地是一个声明,它是编译器唯一允许的。除此以外,Instrument5中没有一个方法被声明为public,但它们都会自动获得public属性。如下所示:

270-271页程序

代码剩余的部分按相同的方式工作。我们可以自由决定上溯造型到一个名为Instrument5的“普通”类,一个名为Instrument5的“抽象”类,或者一个名为Instrument5的“接口”。所有行为都是相同的。事实上,我们在tune()方法中可以发现没有任何证据显示Instrument5到底是个“普通”类、“抽象”类还是一个“接口”。这是做是故意的:每种方法都使程序员能对对象的创建与使用进行不同的控制。

7.5.1 Java的“多重继承”
接口只是比抽象类“更纯”的一种形式。它的用途并不止那些。由于接口根本没有具体的实施细节——也就是说,没有与存储空间与“接口”关联在一起——所以没有任何办法可以防止多个接口合并到一起。这一点是至关重要的,因为我们经常都需要表达这样一个意思:“x从属于a,也从属于b,也从属于c”。在C++中,将多个类合并到一起的行动称作“多重继承”,而且操作较为不便,因为每个类都可能有一套自己的实施细节。在Java中,我们可采取同样的行动,但只有其中一个类拥有具体的实施细节。所以在合并多个接口的时候,C++的问题不会在Java中重演。如下所示:

272页图

在一个衍生类中,我们并不一定要拥有一个抽象或具体(没有抽象方法)的基础类。如果确实想从一个非接口继承,那么只能从一个继承。剩余的所有基本元素都必须是“接口”。我们将所有接口名置于implements关键字的后面,并用逗号分隔它们。可根据需要使用多个接口,而且每个接口都会成为一个独立的类型,可对其进行上溯造型。下面这个例子展示了一个“具体”类同几个接口合并的情况,它最终生成了一个新类:

272-273页程序

从中可以看到,Hero将具体类ActionCharacter同接口CanFight,CanSwim以及CanFly合并起来。按这种形式合并一个具体类与接口的时候,具体类必须首先出现,然后才是接口(否则编译器会报错)。
请注意fight()的签名在CanFight接口与ActionCharacter类中是相同的,而且没有在Hero中为fight()提供一个具体的定义。接口的规则是:我们可以从它继承(稍后就会看到),但这样得到的将是另一个接口。如果想创建新类型的一个对象,它就必须是已提供所有定义的一个类。尽管Hero没有为fight()明确地提供一个定义,但定义是随同ActionCharacter来的,所以这个定义会自动提供,我们可以创建Hero的对象。
在类Adventure中,我们可看到共有四个方法,它们将不同的接口和具体类作为自己的自变量使用。创建一个Hero对象后,它可以传递给这些方法中的任何一个。这意味着它们会依次上溯造型到每一个接口。由于接口是用Java设计的,所以这样做不会有任何问题,而且程序员不必对此加以任何特别的关注。
注意上述例子已向我们揭示了接口最关键的作用,也是使用接口最重要的一个原因:能上溯造型至多个基础类。使用接口的第二个原因与使用抽象基础类的原因是一样的:防止客户程序员制作这个类的一个对象,以及规定它仅仅是一个接口。这样便带来了一个问题:到底应该使用一个接口还是一个抽象类呢?若使用接口,我们可以同时获得抽象类以及接口的好处。所以假如想创建的基础类没有任何方法定义或者成员变量,那么无论如何都愿意使用接口,而不要选择抽象类。事实上,如果事先知道某种东西会成为基础类,那么第一个选择就是把它变成一个接口。只有在必须使用方法定义或者成员变量的时候,才应考虑采用抽象类。

7.5.2 通过继承扩展接口
利用继承技术,可方便地为一个接口添加新的方法声明,也可以将几个接口合并成一个新接口。在这两种情况下,最终得到的都是一个新接口,如下例所示:

274-275页程序

DangerousMonster是对Monster的一个简单的扩展,最终生成了一个新接口。这是在DragonZilla里实现的。
Vampire的语法仅在继承接口时才可使用。通常,我们只能对单独一个类应用extends(扩展)关键字。但由于接口可能由多个其他接口构成,所以在构建一个新接口时,extends可能引用多个基础接口。正如大家看到的那样,接口的名字只是简单地使用逗号分隔。


    
 
 

您可能感兴趣的文章:

  • 请问:make, makefile, configure,分别是什么啊,它们之间有什么关系啊 iis7站长之家
  • 急,请问如何修改网络接口eth为其它名称,如网络接口为abc0, abc1,要修改哪个配置文件?
  • 请问有没有Linux下SOCKET服务端和客户端的接口函数!!
  • 请问TreeCellRenderer接口主要用来干什么啊?
  • 急,请问Linux中如何像windows获取网络接口是否插入网线???
  • 请问Linux下要获得网络接口的相关信息,像ifconfig,netstat那样
  • 我的鼠标时usb接口并且是光电3键鼠标,请问如何在redhat9下使用?
  • 请问在编译oci接口程序时使用哪些库??
  • 请问高手:EJB中的远程接口、本地接口、HOME接口的联系与区别是什么?应用时应注意哪些问题?
  • 请问论坛上有没有对LINUX下的视频接口V4L2了解的吗?
  • 请问在RedHat7.1上可以用usb接口的easyDisk吗?
  • 请问类和接口的区别
  • 请问:访问接口的api,或者类有哪些?如何使用?
  • 请问,红外接口怎样测试?
  • 请问如何在Linux下获得网卡的接口速率?
  • 想请问一下大家终端接口tty1-6
  • 请问为什麽在J2ee中客户端(测试时)用jndi定位enterprise bean的时候,可以把远程接口实例化?接口不是不可以生成对象的吗?
  • 请问, android+linux内核 平台上, 有一个串口接口的外设置芯片, 想对它进行初化, 一般根据该平台下什么驱动改写?
  • 请问Runnable接口为什么能实现多线程?
  • 请问如何在red hat linux 9中使用USB接口,谢谢
  • 请问jsp和serlet之间怎么通讯,jsp和jsp之间呢?
  • 正想学linux 请问red hat版本之间的问题
  • 请问怎样在两个Frame之间通信
  • beyond_xiruo(希偌):请问我要删除某个DIV,那在<%.....%>之间的代码该怎么写???多谢!
  • 请问各位大虾,怎么实现三层页面之间的参数传递?
  • 请问<%@include file="abc.jsp"%>与<jsp:include page="abc.jsp"/>之间的差别
  • 请问如何在两个web服务器之间实现通信?
  • 请问怎么在windows和solaris之间互连和互传文件 谢谢!!
  • 请问如何判断字符串中的字符在a~z之间
  • 两台不同城市的服务器之间要进行数据传输,请问具体的该怎么实现(红帽子)
  • 请问:make, makefile, configure,分别是什么啊,它们之间有什么关系啊
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请问:我知道路由器的telnet密码,但忘记了enable 密码,请问如何是好?
  • 请问那里有SYBASE的jbdb 2.0下载;jspsmartupload可以直接将文件上传到数据库,请问如何使用
  • 请问最新的reahat9.0是基于什么核心的?2.4?2.6?请问那里能下载?
  • 请问:请问哪里有关于linux基本操作命令讲解的资料下载,最好是幻灯片格式的.
  • 请问,我试图用#admintool&图形工具命令来安装sun workshop5.0,为什么进入的却是用户管理界面?请问具体该如何在solaris下安装应用软件
  • 请问在Redhat 9里,我从登录就是图形介面,请问如何在图形介面内进入命令行方式呢,谢谢
  • 请问玩过SOLARIS的高手门,在不正常关机后,就不能启动到windows公用桌面了,只能在命令提示模式下了,请问怎么解决这个问题啊?急~!~!
  • 请问:我在redhat下装了bochs-2.2.1-1.rpm,.装了后,想设置一下,但找不到bochsrc.fda.bxrc,请问这个文件在哪个曰录下啊。
  • 请问:在配置Qt时,很多文档都说在.profile,.login里加东西,但是我好像没有发现有这两个文件上,请问这些文件在哪个目录下啊
  • 请问:在GCC里的C程序里的变量的声明是不是只能在前面,而且相同类型的变量的声明只能放在一起?如果不是,请问怎么样可以解决这个问题.
  • 请问各位大虾,小弟今天开始学jsp了,这学期我们有java课,所以已经下载了jdk(好象是1.2),请问我的98环境怎么配置jsp环境呀?我的jdk可以运行.java程序,别的我就不知道了....谢谢!
  • 主机是WIN2000,我用的是LUNIX,请问是否可以共享上网? 如果可以请问如何设置? 500分答谢,龟儿食言!
  • 请问linux下GUI开发的问题!
  • 请问出现fstab文件丢失该怎么修复呀?
  • 请问这个方法如何调用?
  • 请问一个奇怪的问题!
  • 请问在网页中打开的新窗口,如何让其居中。
  • 请问我该学什么了
  • 请问安装zhcon,cxterm问题
  • 非常急! 请问daemontools 在red hat 9下的安装问题? 在线等待


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3