`
JadeLuo
  • 浏览: 434564 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

什么时候用抽象类,什么时候用接口 收藏

阅读更多

什么时候用抽象类,什么时候用接口

“接口是完全抽象的成员集合,它的成员都无法在接口定义时实现,我们可以将它看作是为操作定义合同,接口的实现完全留给开发者去做。它们之间的区别,如果认真分析,还是有不少的:在JAVA中,类只能是从一个基类继承,所以如果要使用抽象类为一组类提供多态性,这些类必须都是从那个类继承的;接口就不一样了,它不但可以用一个类或结构实现多个接口,一个接口还可以有多个实现。”
       抽象类是一种不能实例化而必须从中继承的类。抽象类可以完全实现,但更常见的是部分实现或者根本不实现,从而封装继承类的通用功能,它可以提供已实现的成员,因此,可以用抽象类确保特定数量的相同功能,但不能用接口这样做。
“也就是说,它们在提供多态性的问题上是有差别的?”我好象听懂了点什么。
“如果预计要创建组件的多个版本,我们应该创建抽象类。这是因为,抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。这是好处,当然也是问题.另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。所以,如果创建的功能将在大范围的全异对象间使用,则使用接口。”------:“能不能这样说,抽象类主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。”
我上午跟你说,要创建控件,首先就是要对一些接口进行实现以让系统能够识别(详见前文《接口》)。而各个控件之间的联系其实关联性并不大。所以,它们的基础大都是接口。但是,我们要注意一点,在组件设计时,如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。这是因为我们刚才说过的原因,抽象类允许部分实现类,而接口不包含任何成员的实现。”

“唔,明白了,它们之间的区别有点明白了。”我默默地点了点头。
       “另外,有个通用的设计思想,如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。”
“看来设计的问题还是蛮大的,一般来说,怎么设计接口呢?”我接着问。

“为什么你所看到的编程书籍也好,程序例程也好,极少有对接口的描述,而对类实现继承的例子比比皆是?这就从一个侧面给我们提了一个醒,如果使用适当,接口可以成为很有用的工具。但如果使用不当,它们会变得非常棘手,甚至妨碍有效的编程。接口的设计与使用其实是一项高明的艺术。”

,“通过接口与实现的方式,我们可以将同一类型的程序运用在不同的对象上面,而且不必修改原有类,相对子程序必须通过修改源程序代码才能够达到重用的目的,接口与实现不仅是伟大的进步,也是境界极高的程序设计艺术。”  

“但是,最大的问题还是集中在接口设计上。接口一旦被定义和接受,就必须保持不变,以保护为使用该接口而编写的应用程序。接口发布后,就不能对其进行更改。这是我们进行组件设计的一个重要原则,叫做‘接口不变性’。”

“我已经反反复复强调过,创建一个接口就是在创建一个定义,接口定义发布后则永远不能更改。接口不变性,就是为了保护为使用接口而编写的现有系统。当接口设计与需求有所出入,确认需要大幅度变更时,我们应该创建新的接口。一般命名方式是,新接口可以通过在原来的接口名称后追加一个数字‘2’来命名,以显示出它与现有接口的关系。然后通过接口继承来创建新接口。”

  “可是,如果需求分析得不好,岂不是会出现一大堆的派生接口了?”我不免有点顾虑。

“这是肯定的,而且过于频繁地生成新接口,会因未使用的接口实现而使组件变得很庞大。有经验的设计师,在充分分析需求后,设计出的接口往往很小且相互独立,减少了性能问题发生的可能。”

“这种分解能力倒真的是艺术呀!”我不禁为之叹服。

“当然,一般来说,我们会把确定哪些属性和方法属于接口的设计过程称为‘接口分解’。基本准则是,应在一个接口中将紧密相关的几个功能聚合为一组。功能太多会使接口不便于运行,而过于细分功能将导致额外的系统开销并降低使用的简易性。掌握分解的这个度的能力是需要不断的在技术上进行磨炼,以及在对每个项目深入分析与理解的基础上才能得到的。”

接口与类实现继承相比,好处有什么?”:“我试着说一下吧,总体而言,接口是一种非常有效的编程方法,它让对象的定义与实现分离,从而可以在不破坏现有应用程序的情况下使对象得以完善与进化。接口消除了实现继承的一个大问题,就是在对设计实施后再对其进行更改时很可能对代码产生破坏。即使实现继承允许类从基类继承实现,在类首次发布时仍然会使我们不得不为设计做很多的抉择。如果原有的设想不正确,并非总可以在以后的版本中对代码进行安全的更改。比如,我们定义了一个基类的方法,它需要一个 Integer 参数,而后来又确定该参数应该为 Long 数据类型。我们无法安全更改原始类,因为为从原始类派生的类所设计的应用程序可能无法进行正确编译。这一问题会扩大化,因为单个基类会影响几百个子类。”

“那用重载原始类并采用一个Long类型的参数,不就能解决这个问题了吗?”大李提了个问题。

“这个么?”我想了一下,“可是,这样不一定能达到满意的效果,因为一个派生类可能需要对采用整数的方法进行重写,如果取 Long 数据类型的方法不能被重写,该派生类可能无法正常运行。”

“那用接口怎么做?”大李不依不挠地继续问。

“办法就是发布接受新数据类型的更新接口。”我一下子就回答出来了。

“看来你已经掌握了接口操作的基本环节了。”大李的评语真让我高兴。“我再帮你总结一下,使用接口继承而不用类继承的主要原因有:在应用程序要求很多可能不相关的对象类型以提供某种功能的情况下,用接口适用性会更强;接口比基类更灵活,因为可以定义单个实现来实现多个接口;在无需从基类继承实现的情况下,接口更好;在无法使用类继承的情况下接口是很有用的。例如,结构无法从类继承,但它们可以实现接口。”
分享到:
评论

相关推荐

    JAVA基础知识精华总结 收藏

    - 间接继承抽象类的类可以不实现抽象类中的抽象方法,只要它仍然被声明为抽象类即可。 #### final关键字 - **final对象的特性**: - 一个对象被声明为`final`,并不代表不能改变对象的成员属性,仍然可以对其...

    抽象工厂模式介绍.pptx

    **抽象工厂模式**是一种设计模式,属于对象创建型模式,它的主要目的是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。这种模式适用于当系统需要创建的对象属于多个产品等级结构,每个等级...

    微型计算机原理与接口技术课件教案(含作业)

    微型计算机原理与接口技术是计算机科学与技术领域中的核心课程之一,主要研究计算机硬件系统的基本构成、工作原理以及与...因此,这份“微型计算机原理与接口技术课件教案”是非常宝贵的教育资源,值得收藏和反复研读。

    C#面试题 收藏 基础题

    5. **接口与抽象类的区别**: - **接口**定义行为规范,强制实现接口的类实现接口中所有的方法。接口不能包含方法的实现,只能包含方法、属性、事件和索引器的签名。 - **抽象类**可以包含已实现的方法和字段,...

    精品资料(2021-2022年收藏)面向对象技术Java期末复习试卷三.doc

    抽象类可以包含非抽象方法,且可以创建其子类的对象,但抽象类自身不能被实例化,选项A错误。 在Java面向对象编程中,理解这些基本概念至关重要,包括类、对象、数据类型、方法、以及接口等,它们共同构成了Java...

    精品资料(2021-2022年收藏)面向对象技术Java期末复习试卷四.docx

    3. 抽象类与接口:抽象类可以包含非抽象方法,而不一定每个抽象类都必须定义抽象方法。选项A错误。定义了抽象方法的类必须是抽象类,这是正确的(选项B)。接口中定义的所有方法默认都是抽象的,且接口中的成员变量...

    精品资料(2021-2022年收藏)面向对象技术Java期末复习试卷五.doc

    - `GeometricObject`是一个抽象类,因为它包含一个抽象方法`compareTo()`,并且类前有`abstract`关键字,表明它不能被实例化。 - 抽象方法在抽象类中定义但不提供实现,具体实现由子类完成。 6. **Comparable接口...

    2021-2022年收藏的精品资料33条C#.Net经典面试题目及答案.doc

    4. **C#中的抽象类和接口有什么区别?** 抽象类可以包含抽象方法和非抽象方法,而接口只能包含方法签名,不能有实现。一个类只能继承一个抽象类,但可以实现多个接口。 5. **什么是委托?** 委托是.NET中的类型安全...

    WinCE流设备驱动简介及GPIO驱动的实现收藏

    硬件抽象层负责将硬件资源抽象成一个统一的接口,流设备驱动则负责将这个接口导出到应用程序中。 在流设备驱动的实现中,需要将 GPIO 控制器注册到 Device Manager 中,然后在应用程序中使用 CreateFile 函数打开 ...

    收藏之---PHP实用指南1.0.CHM

    1. **产品接口/抽象类**:定义了所有创建的对象的公共接口,使得任何返回的产品都符合这个接口。 2. **具体产品类**:实现了产品接口的具体对象,它们是工厂方法要创建的对象。 3. **工厂接口**:定义了一个创建产品...

    多态性与虚函数讲稿.pptx

    多态性是面向对象编程中的核心...虚函数和虚析构函数是实现动态多态性的重要工具,而纯虚函数和抽象类则用于定义接口,促进代码的模块化和设计的灵活性。理解和掌握这些知识点对于编写高质量的面向对象程序至关重要。

    java面试题库 整合完美收藏版

    2. 面向对象:理解类与对象的概念,掌握构造函数、抽象类、接口、访问修饰符、重写和重载的区别。 3. 异常处理:异常的分类、捕获和抛出,理解finally块的作用。 二、Java内存管理 1. 内存区域:堆、栈、方法区、...

    C技巧经典收藏版集.pdf

    这是因为接口定义了一种通用的契约,任何实现了该接口的类都可以互换使用,从而增强了代码的灵活性和可扩展性。 例如,文件中的`LoadList`函数最初是针对数组设计的。如果后续需求改变,需要处理的数据源变成了...

    Java基础知识总结 - 超详细篇收藏.zip

    9. **接口与抽象类**:接口用于定义一组方法,但不提供实现,而抽象类可以包含抽象方法(没有实现的方法)和具体方法。两者都是实现多态的方式,但接口更强调行为的规范,而抽象类则更多关注部分实现。 10. **反射...

    Java经典代码(绝对值得收藏)

    经典代码中可能会展示如何设计良好的类结构、接口实现、抽象类使用以及如何通过多态提高代码的灵活性。 3. **异常处理**:Java的异常处理机制是其强大的特性之一,使用try-catch-finally语句块可以捕获并处理运行时...

    java面向对象知识汇总

    2. 抽象方法:没有具体实现的方法,必须在抽象类或接口中声明。子类必须实现所有抽象方法才能被实例化。 六、访问控制 1. 访问修饰符:`private`(私有)、`default`(默认,包内可见)、`protected`(受保护的)和...

Global site tag (gtag.js) - Google Analytics