`
ericbaner
  • 浏览: 176976 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

接口与抽象类

 
阅读更多
以下为选摘自网络,罗列至此:
接口就跟U盘的USB接口一样,可以插拔。。
当你要完成一个功能的时候,两个事物联系不大,可以用接口。
抽象类着重继承关系。如果两个东西可以看成继承关系,用抽象类。
你要弄一个有警报器的门。
你可以定义一个抽象door类,门有close和open的方法。也定义到这个抽象类里。
但这个警报器,跟门一般关系不大。。所以,你可以用接口.

然后这个带警报器的门就可以是继承door这个类并实现警报器接口。

 

抽象类:首先抽象类也是一个类,什么是类呢?类就是一些对象的抽象,所以抽象类也要是能抽象出来的,比如说人,人就是男人和女人的抽象,抽象类还有另一个特点,就是不能被实例化,比如说人:人分为男人和女人,就不能再分了,所以new一个人的时候,要么new一个男人,要么new一个女人,单独的new一个人就没有任何意义,因为人这个概念不具体,所以不能new
接口:接口是表示一组功能,只要实现这个接口便能拥有这个功能,比如飞,你可以把飞抽象出一个接口,你想让谁飞,那就让它实现这个接口就行了。
接口一旦被定义和接受,就必须保持不变,以保护为使用该接口而编写的应用程序。接口发布后,就不能对其进行更改。这是我们进行组件设计的一个重要原则,叫做 ‘接口不变性’
共同点是他们都可以实现多态。
不同点在于设计抽象类和接口的目的和使用方式有所不同,抽象类是为继承而精心设计的,接口则更多以组合的方式使用。

如果你的业务中可以抽象出一个通用的处理过程,只是某些局部传递的状态或参数有所不同,这时可以考虑使用抽象类。否则在一般的情况下,优先使用接口和组合的形式,这样使代码之间的耦合度降低。

一个比较典型的抽象类使用范例是模板模式,当然也有使用组合来实现的模板。另一个使用抽象类的情形,比如很多场合下特别是对一个声明了相当数量方法的接口,提供一个类似模板的默认实现类是很有好处的,比如spring提供的一些template,dom4j提供的VisitorSupport等。甚至在effective java里已经将这种方式提倡成一种最佳实践。
接口和抽象类都能描述一般性的公有特征。一般来说,强是关系(strong is-a relationship)清晰地描述了父子关系,应该用类模拟,比如苹果是一种水果;而弱是关系(weak is-a relationship)是指对象具有某种属性,适合用接口模拟,比如苹果是可以吃的。

由于子类只能扩展一个父类,而能实现多个接口,所以接口比抽象类更灵活。但是接口不能包括具体的方法,而抽象类可以,要将两种好处结合起来,可以创建一个接口和一个实现该接口的抽象类(便利类),然后根据情况决定使用哪个。

接口不变性是指不改变接口的使用方法,但是可以改变接口的具体实现方法,而接口的实现对用户是透明的,用户不需要关心接口的实现,只要知道如何使用接口就行了,所以接口不变性为用户提供了便利。
抽象类也一样,内部实现可以因为需要而更改(比如改进了算法),但是提供给用户的使用方法不要轻易改变
接口只有方法声明没实现,本质上是一个规约;抽象类可以有实现。
语法上的区别就不说了;
从编程的角度,如果你想实现某些功能代码的重用,显然要用抽象类;
从设计的层面看,抽象类和派生类是Is-a的关系(就好像狗是动物、鹅是动物);而接口和实现类就没有这个关系(就好像狗可以看门、鹅也能看门,但它们本质上不是“看门器”)
抽象类中有属性及属性值。
接口中除了常量外,只能有方法。

通常,反映一个类的基本属性的父类,用抽象类。
接口通常比较简洁,目的明确,推崇多用接口。

我们可以把父类都写成接口,到了方便的情况下将其中一个接口改成父类。
接口       更像是特定的功能,但不明确给谁用
抽象类   更像是知道儿子什么样,就是去猜他老爸的样子。
1:声明方法的存在而不去实现它的类被叫做抽象类,抽象类中有抽象方法,需要继承它的类去重写。
2:接口中的所有方法必须是抽象方法,由实现它的类重写。
3:java是单继承,多实现的机制,如果你已经继承了一个类,还需要继承其他类,不妨去实现接口来的灵活,因为类只能继承一个,接口却可以实现很多
接口是一种协定,抽象类则相当于类模板。
如果一个类型必须实现多个协定,或者协定适用于多种类型,使用接口。
虽然抽象类和接口都支持将协定与实现分离开来,但接口不能指定以后版本中的新成员,而抽象类可以根据需要添加成员以支持更多功能。
如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。

如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。

 

如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。

 

如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。

什么时候该用抽象,什么时候用接口呢?

   A. 根据我的理解,抽象强调的是 is-a 关系,即一种继承层次(比如模板方法模式),如果有多个模板且这些模板的基本结构相似,那么可以抽象出一个父模板,即使用抽象。

   B. 而接口更侧重的是职责(最小接口原则、接口分离原则等等),接口定义的是一种合约或者规范(因为不提供任何实现)。

   C. 针对接口编程比针对抽象类编程会有更小的耦合度,因为针对抽象类编程,Client还是会与抽象类耦合

   举个例子,我们已经有Cat和Dog两个类,显然它们都是哺乳动物,从这一层次来看,我们应该为它们抽象出一个Mammal(哺乳动物的英文)类。而它们都有walk和suckle(哺乳)行为(还有其他行为,简单起见,就两个行为好了)。如下图所示:

   这个很简单,每个Java初学者在学到继承章节都会遇到这个问题。而针对接口编程如何引出呢?不着急。假设现在我们需要扩展两个鸟类(Bird),比如Swallow(燕子)和Eagle(老鹰),最简单的方法当然是另外创建一个Bird父类,父类下面有两个子类:Swallow和Eagle。因为鸟类和哺乳动物都是动物,所以再抽象一个Animal父类。

   现在总共有七个类,试想如果我们又需要增加Shark(鲸鱼)和Octopus(章鱼)两类,那么我们又要增加一个Acquatic类,其下两个子类,Acquatic又继承了Animal类,现在有十个类。

   如果继续下去,类将越来越多,即产生所谓的”类爆炸“问题。

   再进一步,我们要考虑一些特殊的情况:蝙蝠、鲸鱼、飞鱼。

   首先蝙蝠既是哺乳动物,但也有鸟类的行为fly()。鲸鱼既是哺乳动物,又具有水生动物的一些行为如suckle(),比如swim()。尤其是飞鱼,它既具有水生动物的行为swim(),同时也拥有鸟类的行为fly()。那我们该怎么办?

   让蝙蝠同时继承哺乳动物类和鸟类?让鲸鱼同时继承哺乳动物类和水生动物类?

   想法是可以的,但是这样不提会带来更加复杂的类关系,而且Java本身也不支持多继承机制。那么该如何解决?

   解决方案是使用接口,接口能弥补实现这一特性。如下:

  

   这里使用了桥接模式(抽象与实现相分离)。现在你要加一个蝙蝠类、飞鱼类、鲸鱼类都随便你,甚至你要加一个鸭嘴兽(鸟+兽+鱼的行为都有)都行。

   你或许会说这下有11个类了,比前面的还多了。不着急,我们不妨计算下,前面的例子对于每增加一个分类(水生动物或哺乳动物)增加3个类。这样如果分类有N个,且每个分类下面有2个子类,那么共有3N+1个类。而这种方法的类总数为2N+7个,随着N的增大,这种方案的优势就开始明显了。

   这就是面向接口编程的威力。   

 

以一个Door的为例,该Door具有执行两个动作 Open 和Close

此时可以用接口和抽象类两种方法来定义

---------

abstract class Door{

     abstract void open();

     abstract void close();

}

---------

interface Door{

    void open();

    void close();

}

 

其他的具体的Door可以用上述接口和抽象类中的任何一个,现在若要求Door还具有报警的功能呢 如何处理

解决方案一:

---------

abstract class Door{

     abstract void open();

     abstract void close();

     abstract void alarm();

}

interface Door{

    void open();

    void close();

    void alarm();

}

那么具有报警功能的Door如下:

 

class AlarmDoor extends Door{

      void open();

      void close();

      void alarm();

}

class AlarmDoor implements Door{

      void open();

      void close();

      void alarm();

}

 

这种方法违反了ISP原则:在Door的定义中,把Door概念本身固有的行为方法和 另外一个概念“报警器”的行为方法混在了一起,若是这样,那些仅仅依赖于Door这个概念的模块,会因为“报警器”这个概念的改变而改变。

 

解决方案二:

既然open,close和alram是两个不同的概念,根据ISP原则应该分别定义在两个概念的抽象类中,定义方式有 定义2个抽象类,定义一个抽象类一个接口。

但是Java不支持多继承 所以最后方案如下:

---------------------------------------------

class AlarmDoor extends Door{

      void open();

      void close();

}

 

 

interface Alarm {

   void alarm()

}

 

class AlarmDoor extends Door implements Alarm{

    void open(){.....}

    void close(){.....}

    void alarm(){.....}

}

 

分享到:
评论

相关推荐

    接口与抽象类区别

    接口与抽象类区别 在软件开发中,接口和抽象类是两个常用的概念,但它们之间的区别却让许多人感到困惑。那么,什么是抽象类和接口?它们之间有什么区别?下面,我们就来详细地探讨这个问题。 一、抽象类 抽象类是...

    java中接口与抽象类的详细分析与比较

    在Java编程语言中,接口(Interface)和抽象类(Abstract Class)都是用于实现多态性的关键...通过阅读"java中接口与抽象类的详细分析与比较.doc"文档,你将获得更深入的洞察和实践指导,进一步提升你的Java编程能力。

    Java语言的接口与抽象类

    4. 绑定关系:抽象类与子类有从属绑定,接口与实现类之间没有这种绑定。 5. 动态绑定:两者都支持运行时多态,即父类引用指向子类对象。 在使用原则方面: 1. 抽象类:通常用于一组相关子类共享代码,减少代码冗余...

    C#类、接口、虚方法和抽象方法-接口与抽象类的区别实例

    C#类、接口、虚方法和抽象方法-接口与抽象类的区别实例 C#类、接口、虚方法和抽象方法-接口与抽象类的区别实例

    Java接口与抽象类课件

    Java接口与抽象类的课件,适合初学者,主要对接口与抽象类进行简要介绍,PPT版本。

    Kotlin接口与抽象类的详细解析及应用场景

    接着深入探讨了类与对象的基本用法,并详细讲解了接口和抽象类的作用,包括它们的异同点和组合使用方式。文章通过丰富的示例代码展示了如何在实际编程中利用接口和抽象类来实现多态和代码复用。 适合人群:初学者到...

    接口与抽象类区别PPT优秀资料.ppt

    3. 抽象类与接口的选择 在选择抽象类定义方式时,需要考虑问题领域的本质理解和设计意图是否正确、合理。abstract class 和 interface 之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,但是...

    C#面向对象高级:接口与抽象类的深度解析及应用场景

    内容概要:本文详细介绍了C#面向对象编程中的接口与抽象类的定义、实现及其在实际开发中的应用场景。首先,文章回顾了面向对象编程的基础概念,包括类与对象、封装、继承和多态。接着,详细探讨了接口和抽象类的定义...

    接口与抽象类的入门小程序(C# VS2010 )

    本项目"接口与抽象类的入门小程序"是针对C#开发者,使用Visual Studio 2010编译环境的一个实践教程,旨在帮助初学者理解和掌握这两种关键的类组织结构。 接口(Interface)在C#中是一种完全抽象的类型,它定义了一...

    Kotlin接口与抽象类详解及其应用

    最后比较了接口和抽象类的区别,讨论了它们在不同场景下的最佳实践,并探讨了密封类与接口结合使用的优点。 适合人群:有一定Kotlin基础的开发者,特别是对面向对象编程和设计模式感兴趣的程序员。 使用场景及目标:...

    java 抽象类与接口的练习

    在Java编程语言中,抽象类和接口是两种重要的面向对象设计...通过这样的练习,你可以更好地理解和掌握Java中的抽象类与接口,以及它们在实际开发中的应用。在实践中不断尝试和调试,将有助于深化对这两个概念的理解。

    java高级类操作 接口与抽象类的操作

    Java中的高级类操作涉及到抽象类和接口的使用。抽象类是一种不能被实例化的类,它主要用来被其他类继承,定义共有的属性和方法。接口则是一种完全抽象的类型,用于定义一组方法签名,实现多继承的效果。 首先,让...

    接口与抽象类的区别以及一些java基础

    // 接口中的方法只能通过对象调用,不能通过类名调用 }}在Java中,接口和抽象类都是用于实现多态性的重要工具,但它们之间存在显著的区别: 1. **接口(Interface)**: - 接口是一个完全抽象的类型,它只包含...

    特征之接口与抽象类PPT学习教案.pptx

    特征之接口与抽象类PPT学习教案.pptx

    接口与抽象类的主要区别

    在编程领域,接口和抽象类是面向对象设计中两种重要的机制,它们用于定义类的行为和结构。虽然两者在某些方面有相似之处,但它们在概念、实现方式和用途上存在显著差异。 首先,抽象类是一种特殊的类,它不能被实例...

    C#接口与抽象类的详解

    在编程语言中,C#提供了两种机制来实现多态性和代码重用,即抽象类和接口。虽然两者在某些方面有相似之处,但它们在设计理念和使用场景上有显著的差异。 首先,我们来深入理解抽象类。抽象类是一种特殊的类,它不能...

    接口和抽象类的区别(面向对象)

    接口与抽象类的区别 抽象方法是必须实现的方法。就象动物都要呼吸。但是鱼用鳃呼吸,猪用肺呼吸。 动物类要有呼吸方法。怎么呼吸就是子类的事了。 现在有很多讨论和建议提倡用interface代替abstract类,两者从...

Global site tag (gtag.js) - Google Analytics