AutoCAD 3DMAX C言语 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab运用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 主页 > JAVA编程

详细解析Java中笼统类和接口的差异

188bet.com网 2015-09-03 http://www.pvc01.com
  在Java言语中, abstract class 和interface 是支撑笼统类界说的两种机制。正是由于这两种机制的存在,才赋予了Java强壮的 面向目标才干。abstract class和interface之间在关于笼统类界说的支撑方面具有很大的相似性,乃至可以彼此替换,因而许多开发者在进 行笼统类界说时关于abstract class和interface的挑选显得比较随意。其实,两者之间仍是有很大的差异的,关于它们的挑选乃至反映出对 于问题范畴实质的了解、关于规划目的的了解是否正确、合理。本文将对它们之间的差异进行一番剖析,企图给开发者供给一个在二者之间进行挑选的根据。

  了解笼统类

  abstract class和interface在Java言语中都是用来进行笼统类(本文 中的笼统类并非从abstract class翻译而来,它表明的是一个笼统体,而abstract class为Java言语中用于界说笼统类的一种办法, 请读者留意差异)界说的,那么什么是笼统类,运用笼统类能为咱们带来什么优点呢?

  在 面向目标的概念中,咱们知道一切的目标都是经过类来描绘的,可是反过来却不是这样。并不是 一切的类都是用来描绘目标的,假如一个类中没有包括满足的信息来描绘一个详细的目标,这样的类便是笼统类。笼统类往往用来表征咱们在对问题范畴进行剖析、 规划中得出的笼统概念,是对一系列看上去不同,可是实质上相同的详细概念的笼统。比方:假如咱们进行一个图形修正软件的开发,就会发现问题范畴存在着圆、 三角形这样一些详细概念,它们是不同的,可是它们又都归于形状这样一个概念,形状这个概念在问题范畴是不存在的,它便是一个笼统概念。正是由于笼统的概念 在问题范畴没有对应的详细概念,所以用以表征笼统概念的笼统类是不可以实例化的。

  在面向目标范畴,笼统类首要用来进行类型躲藏。 咱们可以构造出一个固定的一组行为的笼统描 述,可是这组行为却可以有恣意个或许的详细完结办法。这个笼统描绘便是笼统类,而这一组恣意个或许的详细完结则体现为一切或许的派生类。模块可以操作一个 笼统体。由于模块依赖于一个固定的笼统体,因而它可以是不允许修正的;一同,经过从这个笼统体派生,也可扩展此模块的行为功用。了解OCP的读者必定知 道,为了可以完结面向目标规划的一个最中心的准则OCP(Open-Closed Principle),笼统类是其间的关键地点。

  从语法界说层面看abstract class 和 interface

  在语法层面,Java言语关于abstract class和interface给出了不同的界说办法,下面以界说一个名为Demo的笼统类为例来阐明这种不同。

  运用abstract class的办法界说Demo笼统类的办法如下:

abstract class Demo{
abstract void method1();
abstract void method2();


  运用interface的办法界说Demo笼统类的办法如下:

interface Demo{
void method1();
void method2();

}

  在abstract class办法中,Demo可以有自己的数据成员,也可以有非 abstract的成员办法,而在interface办法的完结中,Demo只可以有静态的不能被修正的数据成员(也便是有必要是static final 的,不过在interface中一般不界说数据成员),一切的成员办法都是abstract的。从某种意义上说,interface是一种特别办法的 abstract class。

  从编程的视点来看,abstract class和interface都可以用来完结 "design by contract" 的思维。可是在详细的运用上面仍是有一些差异的。

  首要,abstract class 在 Java 言语中表明的是一种承继联系,一个类只能运用一次承继联系(由于Java不支撑多承继 -- 转注)。可是,一个类却可以完结多个interface。或许,这是Java言语的规划者在考虑Java关于多重承继的支撑方面的一种折中考虑吧。

  其次,在abstract class的界说中,咱们可以赋予办法的默许行为。可是在interface的界说中,办法却不能具有默许行为,为了绕过这个约束,有必要运用托付,可是这会添加一些复杂性,有时会形成很大的费事。

  在 笼统类中不能界说默许行为还存在另一个比较严重的问题,那便是或许会形成保护上的费事。因 为假如后来想修正类的界面(一般经过 abstract class 或许interface来表明)以习惯新的状况(比方,添加新的办法或许给已用的办法中添 加新的参数)时,就会十分的费事,或许要花费许多的时刻(关于派生类许多的状况,尤为如此)。可是假如界面是经过abstract class来完结的,那 么或许就只需求修正界说在abstract class中的默许行为就可以了。

  相同,假如不能在笼统类中界说默许行为,就会导致相同的办法完结出现在该笼统类的每一个派生类中,违反了 "one rule,one place" 准则,形成代码重复,相同不利于今后的保护。因而,在abstract class和interface间进行挑选时要十分的当心。

  从规划理念层面看 abstract class 和 interface

  上面首要从语法界说和编程的视点论说了abstract class和interface的区 别,这些层面的差异是比较低层次的、非实质的。本末节将从另一个层面:abstract class和interface所反映出的规划理念,来剖析一下二者的差异。作者以为,从这个层面进行剖析才干了解二者概念的实质地点。

  前面现已提到过,abstract class在Java言语中体现了一种承继联系,要想使得 承继联系合理,父类和派生类之间有必要存在"is-a"联系,即父类和派生类在概念实质上应该是相同的。关于interface来说则否则,并不要求interface的完结者和interface界说在概念实质上是共同的, 只是是完结了interface界说的契约罢了。为了使论说便于了解,下面将经过一个简略的实例进行阐明。

  考虑这样一个比方,假设在咱们的问题范畴中有一个关于Door的笼统概念,该Door具有履行两个动作open和close,此刻咱们可以经过abstract class或许interface来界说一个表明该笼统概念的类型,界说办法别离如下所示:

  运用abstract class办法界说Door:

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

  运用interface办法界说Door:

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

  其他详细的Door类型可以extends运用abstract class办法界说的Door或许implements运用interface办法界说的Door。看起来如同运用abstract class和interface没有大的差异。

  假如现在要求Door还要具有报警的功用。咱们该怎么规划针对该比方的类结构呢(在本例中, 首要是为了展现 abstract class 和interface 反映在规划理念上的差异,其他方面无关的问题都做了简化或许疏忽)?下面将罗列出或许的解 决计划,并从规划理念层面临这些不同的计划进行剖析。

  处理计划一:

  简略的在Door的界说中添加一个alarm办法,如下:

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

  或许

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

  那么具有报警功用的AlarmDoor的界说办法如下:

class AlarmDoor extends Door{
void open(){…}
void close(){…}
void alarm(){…}
}

  或许

class AlarmDoor implements Door{
void open(){…}
void close(){…}
void alarm(){…}

  这种办法违反了面向目标规划中的一个中心准则 ISP (Interface Segregation Principle),在Door的界说中把Door概念自身固有的行为办法和别的一个概念"报警器"的行为方 法混在了一同。这样引起的一个问题是那些只是依赖于Door这个概念的模块会由于"报警器"这个概念的改动(比方:修正alarm办法的参数)而改动,反 之仍然。

  处理计划二:

  已然open、close和alarm归于两个不同的概念,根据ISP准则应该把它们别离定 义在代表这两个概念的笼统类中。界说办法有:这两个概念都运用 abstract class 办法界说;两个概念都运用interface办法界说;一个概念 运用 abstract class 办法界说,另一个概念运用interface办法界说。

  明显,由于Java言语不支撑多重承继,所以两个概念都运用abstract class办法界说是不可行的。后边两种办法都是可行的,可是关于它们的挑选却反映出关于问题范畴中的概念实质的了解、关于规划目的的反映是否正确、合理。咱们一一来剖析、阐明。

  假如两个概念都运用interface办法来界说,那么就反映出两个问题:1、咱们或许没有 了解清楚问题范畴,AlarmDoor在概念实质上到底是Door仍是报警器?2、假如咱们关于问题范畴的了解没有问题,比方:咱们经过关于问题范畴的分 析发现AlarmDoor在概念实质上和Door是共同的,那么咱们在完结时就没有可以正确的提醒咱们的规划目的,由于在这两个概念的界说上(均运用 interface办法界说)反映不出上述意义。

  假如咱们关于问题范畴的了解是:AlarmDoor在概念实质上是Door,一同它有具有报 警的功用。咱们该怎么来规划、完结来清晰的反映出咱们的意思呢?前面现已说过,abstract class在Java言语中表明一种承继联系,而承继联系 在实质上是"is-a"联系。所以关于Door这个概念,咱们应该运用abstarct class办法来界说。别的,AlarmDoor又具有报警功用,说 明它又可以完结报警概念中界说的行为,所以报警概念可以经过interface办法界说。如下所示:

abstract class Door{
abstract void open();
abstract void close();
}
interface Alarm{
void alarm();
}
class Alarm Door extends Door implements Alarm{
void open(){…}
void close(){…}
void alarm(){…}
}

  这种完结办法基本上可以清晰的反映出咱们关于问题范畴的了解,正确的提醒咱们的规划目的。其 实abstract class表明的是"is-a"联系,interface表明的是"like-a"联系,咱们在挑选时可以作为一个根据,当然这是树立在对问题范畴的了解上的,比方:假如咱们以为AlarmDoor在概念实质上是报警器,一同又具有Door的功用,那么上述的界说办法就要反过来了。

  小结

  1.abstract class 在 Java 言语中表明的是一种承继联系,一个类只能运用一次承继联系。可是,一个类却可以完结多个interface。

  2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员办法,而在interface中,只可以有静态的不能被修正的数据成员(也便是有必要是static final的,不过在 interface中一般不界说数据成员),一切的成员办法都是abstract的。

  3.abstract class和interface所反映出的规划理念不同。其实abstract class表明的是"is-a"联系,interface表明的是"like-a"联系。

  4.完结笼统类和接口的类有必要完结其间的一切办法。笼统类中可以有非笼统办法。接口中则不能有完结办法。

  5.接口中界说的变量默许是public static final 型,且有必要给其初值,所以完结类中不能从头界说,也不能改动其值。

  6.笼统类中的变量默许是 friendly 型,其值可以在子类中从头界说,也可以从头赋值。

  7.接口中的办法默许都是 public,abstract 类型的。

  定论

  abstract class 和 interface 是 Java言语中的两种界说笼统类的办法,它们之间有很大的相似性。可是关于它们的挑选却又往往反映出关于问题范畴中的概 念实质的了解、关于规划目的的反映是否正确、合理,由于它们体现了概念间的不同的联系(尽管都可以完结需求的功用)。这其实也是言语的一种的惯用法,期望读者朋友可以细细领会。

 

 

 
阐明
:本教程来历互联网或网友上传或出版商,仅为学习研讨或媒体推行,pvc01.com不确保材料的完整性。
 
上一篇:Java编程技术中汉字问题的剖析及处理  下一篇:争鸣:Java的Web结构 让我怎么去爱你