连载:面向对象葵花宝典:思想.技巧与实践(9) - "抽象类" 详解

2013-11-02  来源:本站原创  分类:编程语言  人气:0 

抽象类是一种特殊的类,其特殊性在于抽象类只能用于继承,不能被实例化为具体的对象。例如在Java中不能new一个抽象类,但可以extends一个抽象类。

抽象类的定义其实很简单,但其使用并不那么简单,有几个问题我们需要深入研究一下。

第一个问题是:有了类,为什么还要抽象类,为什么设计一种只能继承,不能实例化的类?

答案就在于:某些场景下普通类不够用。例如,“苹果”、“桔子”、“香蕉”都是“水果”,这里的“水果”就是一个抽象类。你可以说你喜欢吃“水果”,但你真正吃“水果”的时候,要么是“苹果”,要么是“桔子”,要么是“香蕉”。。。。。。但你绝不可能真正吃到一个叫做“水果”的东东。

从设计的角度来看,抽象类是更高层次的抽象。如果说普通类是从现实对象抽象出来的,那么抽象类就是基于类而抽象出来的。例如上面的样例,从“苹果”、“桔子”、“香蕉”这几个普通类,抽象出了“水果”这个类。

从实现的角度来看,抽象类与普通类不同的地方在于:抽象类有的存在抽象方法(方法只有声明,没有定义),子类必须自己定义这些抽象方法,而不能像普通的方法一样,通过继承就可以获得父类的方法。这一点上来看,抽象类和接口有点类似。

第二个问题是:抽象类和接口有什么区别,为什么有了接口,还要有抽象类?

答案就在于:抽象类本质上还是类,强调一组事物的相似性,包括属性和方法的相似性;而接口只强调方法的相似性,并且仅仅体现在方法声明上的相似性,而没有方法定义上的相似性。

例如:假设我们设计一个游戏,其中使用“苹果”、“桔子”、“香蕉”来做“补血”,“苹果”、“桔子”、“香蕉”都有“颜色”、“重量”这样的属性,但每种水果的补血方式是不一样的。这种情况下,使用抽象类可以很好的表达,我们设计一个抽象类“水果”,将“颜色”、“重量”作为“水果”的属性,“获取颜色”、“获取重量”、“减少重量”等方法作为“水果”的方法,将“补血”作为“水果”的抽象方法。这样设计能够大大减少“苹果”、“桔子”、“香蕉”几个普通类的实现工作量,它们只需要实现“补血”方法,其它的属性和方法都只需继承“水果”类即可。而如果采用接口的方式实现,则“苹果”、“桔子”、“香蕉”每个类都需要自己增加“颜色”、“重量”属性,增加“获取颜色”、“获取重量”、“减少重量”、“补血”等方法,工作量和代码量大大增加。

综合上述的分析,我们可以看出,抽象类看起来是一个介于类和接口之间的一个概念,同时具备类和接口的部分特性。

相关文章
  • 连载:面向对象葵花宝典:思想.技巧与实践(9) - "抽象类" 详解 2013-11-02

    抽象类是一种特殊的类,其特殊性在于抽象类只能用于继承,不能被实例化为具体的对象.例如在Java中不能new一个抽象类,但可以extends一个抽象类. 抽象类的定义其实很简单,但其使用并不那么简单,有几个问题我们需要深入研究一下. 第一个问题是:有了类,为什么还要抽象类,为什么设计一种只能继承,不能实例化的类? 答案就在于:某些场景下普通类不够用.例如,"苹果"."桔子"."香蕉"都是"水果",这里的"水果"

  • 连载:面向对象葵花宝典:思想.技巧与实践(8) - "接口" 详解 2014-08-17

    接口"是我见过的面向对象领域中滥用.乱用.误用最多的术语: 有的人说:兄弟,给我提供一个"查询XXX"的接口...... 有的人说:系统对外提供了"查询"."插入"."更新"."删除"4个接口...... 有的人说:我们要基于"接口"编程...... 有的人说:你这样做破坏了我们的接口设计...... ........... 倒不是在这里指责他们的水平有多差,而是接口这个属于的

  • 连载:面向对象葵花宝典:思想.技巧与实践(10) - "抽象" 详解 2014-10-17

    抽象的中文概念非常形象,简单来说就是"抽取出来比较像的部分". 那么,在面向对象的领域里,抽取什么东西比较像的部分? 还记得前面给类下的定义么?我们一起来回顾一下:类就是一组相似事物的统称. 再结合我们对象的定义:对象就是一个具体的类,一个真实存在的类. 我们就很容易发现了抽象的详细含义:抽取多个对象或者类中比较像的部分. 注: 史派克:<猫和老鼠>中的斗牛犬 这里的抽象分为两个层次: 第一个层次:对象抽象成类. 例如奥巴马和梅西抽象成"人",这一层的抽

  • 连载:面向对象葵花宝典:思想.技巧与实践(3) - 面向过程 vs 面向对象 2014-04-21

    面向过程 在介绍面向对象之前,我们首先要介绍"面向过程",首先是因为"面向过程"是软件思想中的鼻祖:其次是因为只有了解了面向过程,你才能更好的了解面向对象!正所谓:知己知彼百战百胜! 面向过程是一种以"过程"作为中心的编程思想,其中过程的含义就是"完成一件事情的步骤". 面向过程其实是一种"机械的思想",它就像流水线一样,一个阶段衔接一个阶段,每个阶段都有自己的输入.处理.输出,而在流水线上流动的就是我们的

  • 连载:面向对象葵花宝典:思想.技巧与实践(6) - 不要说你懂"类" 2014-08-04

    方以类聚,物以群分--<周易易传>. 类是面向对象领域里最基础的一个概念,也是面向对象分析和设计的基石. 然而,如此重要的一个概念,竟然很难找到深入的说明,绝大部分介绍面向对象的书籍或者资料基本上都是这么解释的:"类是一组对象的抽象",这个解释看起来清晰明了,但实际上犯了一个逻辑上的错误:以未明确的概念来解释待明确的概念,什么是对象,什么是抽象,我们都还不知道,你却用这个概念来解释类?那当然看不懂了. 还有另外一个解释:类就是属性和方法的集合!甚至还会给出如下这样的样例:

  • 连载:面向对象葵花宝典:思想.技巧与实践(4) - 面向对象是瑞士军刀还是一把锤子? 2014-12-19

    为什么要面向对象? 可以说,面向过程和计算机是如影随形的.从计算机诞生之日起,面向过程就是占据着主导地位的思想,即使到了现在,面向过程也是无处不在的,C语言.操作系统.协议栈.驱动系统,都是面向过程的代表. 那为什么还会有面向对象的诞生并流行呢?当然是面向过程存在某些不足,如果面向过程足够好,谁还费心费力的去搞另外一套呢? 前面我们提到,面向过程是一种机器的思想,我们以流水线作为类比,那么我们先抛开面向过程,来看看流水线有什么不足. 举个简单的流水线例子:啤酒生产流水线.啤酒生产流水线分为"洗瓶

  • 连载:面向对象葵花宝典:思想.技巧与实践(2) - 面向对象语言发展历史 2015-03-04

    Simula 面向对象技术最早是在编程语言Simula中提出的.1967年5月20日,在挪威奥斯陆郊外的小镇莉沙布举行的IFIPTC-2工作会议上,挪威科学家Ole-JohanDahl和KristenNygaard正式发布了Simula67语言.Simula67被认为是最早的面向对象程序设计语言,是面向对象的开山祖师,它引入了所有后来面向对象程序设计语言所遵循的基础概念:对象.类.继承,但它的实现并不是很完整. Simula虽然最早提出面向对象的概念,但因为其本身复杂,比较难学,而并没有大规模流

  • 连载:面向对象葵花宝典:思想.技巧与实践(5) - 面向对象迷思:面向对象导致性能下降? 2015-01-13

    面向对象会导致性能降低? 这是一个在IT江湖流传已久的传说,很多对面向对象不甚了解.或者一知半解的人,每当需要抵触面向对象时,就会把这条"金科玉律"拿出来救驾! 更要命的是,每个相信这个传说的人都会举一个看起来很显而易见的例子:C和Java的对比! 你可以到网上搜索一大堆C和Java的性能对比,你自己也可以做一个简单的对比测试,我毫不怀疑测试结果肯定是C快,但这能证明面向对象导致性能降低么? 从语言层面来说,面向对象的语言肯定要比面向过程的语言性能要低一些,毕竟这是由处理机制决定的,就

  • 连载:面向对象葵花宝典:思想.技巧与实践(7) - "对象"新解 2015-03-08

    有了"类"的清晰定义后,"对象"就比较容易理解了. 对象就是一个具体的类,一个真实存在的类. 前面我们提到面向对象是对现实世界的模拟,那么对象就是现实世界中存在的"物体". 例如,"人"是一个类,我就是一个"人"的对象,你也是"人"的对象,奥巴马也是"人"的对象...... 又比如:你去国美买冰箱,但国美肯定没有一个单独叫做"冰箱"的东西卖给你,而

  • js面向对象之公有.私有.静态属性和方法详解 2014-09-03

    这篇文章主要详细介绍了js面向对象之公有.私有.静态属性和方法,并附上详细的示例,非常的细致全面,这里推荐给大家,有需要的小伙伴可以参考下 现下,javascript大行其道,对于网站开发人员来说,javascript是必需掌据的一门语言,但随着jquery等框架的流行和使用,许多人对于原生javascript缺乏深入的理解,习惯了函数式的编辑风格,对于闭包.原型总是说不清道不明.对于js面向对象蹩脚的用着,而要了解js面向对象,就必需先了解js中什么是公有方法.特权方法.静态方法 方法/步骤

  • Silverlight游戏设计(Game Design):(五)面向对象的思想塑造游戏对象 2012-03-09

    传说,面向对象的开发模式最初是因为程序员偷懒而不小心诞生的.发展至今,人们从最初的热忠于讨论某某语言是否足够面向对象到现在开始更广泛的关注面向对象的思想而不是具体内容.面向对象的思想其实并不深奥,它存在的目的只有一个:让程序开发更贴近我们的现实世界. 还记得猫.猫叫:狗.狗吃东西吗?无数的程序员都喜欢将此类似的情形设计当作面向对象最好的例子.是的,非常生动且形象:但实际运用中你是否能真正做到举一反三? 回述到游戏设计中,大家是否时常会感觉游戏世界与我们的真实世界如此贴近?游戏中的精灵好比我们人类

  • Lua中的面向对象编程详解 2013-12-16

    这篇文章主要介绍了Lua中的面向对象编程详解,本文讲解了Lua中的类.继承.多重继承等内容,需要的朋友可以参考下 简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: local tb1 = {a = 1, b = 2} local tb2 = {a = 1, b = 2} local tb3 = tb1 if tb1 == tb2 then print("tb1 == tb2") else print("tb1 ~= tb2") e

  • C#面向对象特征的具体实现及作用详解 2014-05-08

    所有的面相对象思想,归根结底是为了简化代码,减少代码量,构建更符合现实生活逻辑的程序代码,从而减轻程序员的负担.不能一味地或者说刻意地去使用面相对象的思想而忽略了程序所实现的功能或者框架,要根据实际情况 众所周知,面向对象编程的特点为:封装.继承.多态.C#是一门完全面向对象的语言,由于比Java推出的时间还要晚,所以对面向对象的思想的体现比Java还要完美,那么在C#中如何体现封装.继承和多态呢?下面举例并进行说明. 1.封装 封装的好处有以下几点: ①数据不外泄,可以做到一定的保护 ②类的使

  • Lua面向对象之多重继承.私密性详解 2014-11-06

    这篇文章主要介绍了Lua面向对象之多重继承.私密性详解,本文讲解了多重继承之在多个类中查找一个字段.多重继承之创建继承多个类的子类.类的私密性等内容,需要的朋友可以参考下 在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少. 本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会. 咳咳,本着坚持不懈.负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!) 1.多重继承之在多个类中查找一个字段 我发现这些高(shen)智(jing

  • Python中的面向对象编程详解(上) 2014-04-17

    这篇文章主要介绍了Python中的面向对象编程详解(上),本文讲解了创建类.实例化类.类属性.特殊方法内建属性.静态变量属性.实例变量属性.方法属性.静态方法.类方法等内容,需要的朋友可以参考下 创建类 Python 类使用 class 关键字来创建.简单的类的声明可以是关键字后紧跟类名: class ClassName(bases): 'class documentation string' #'类文档字符串' class_suite #类体 实例化 通过类名后跟一对圆括号实例化一个类 复制代

  • JavaScript中的alert()函数使用技巧详解 2014-06-20

    这篇文章主要介绍了JavaScript中的alert()函数使用技巧详解,本文讲解了普通弹出.带换行的文本.使用制表符.使用变量.使用样式等选择,需要的朋友可以参考下 在JavaScript代码中,可以使用window对象的alert()函数来显示一段文本,从而进行程序的调试,或者向用户警示相关信息: //Use window object's alert() function window.alert("sample text"); 这一写法可以简化为直接使用alert()函数: 复

  • Python中的面向对象编程详解(下) 2014-07-06

    这篇文章主要介绍了Python中的面向对象编程详解(下),本文讲解了继承.super关键字.重写.多重继承.类.实例和其他对象的内建函数.私有化等内容,需要的朋友可以参考下 继承 继承描述了基类的属性如何"遗传"给派生类.一个子类可以继承它的基类的任何属性,不管是数据属性还是方法. 创建子类的语法看起来与普通(新式)类没有区别,一个类名,后跟一个或多个需要从其中派生的父类: class SubClassName (ParentClass1[, ParentClass2, ...]):

  • apache .htaccess文件详解和配置技巧总结 2014-08-19

    这篇文章主要介绍了apache .htaccess文件详解和配置技巧总结,需要的朋友可以参考下 一..htaccess的基本作用 .htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令. .htaccess主要的作用有:URL重写.自定义错误页面.MIME类型配置以及访问权限控制等.主要体现在伪静态的应用.图片防盗链.自定义404错误页面.阻止/允许特定IP/IP段.目录浏览与主页.禁止访问指定文件类型.文件密码保护等. .htaccess的用途范围主要针对当前目录.

  • 深入理解Android组件间通信机制对面向对象特性的影响详解 2014-08-27

    本篇文章是对Android组件间通信机制对面向对象特性的影响进行了详细的分析介绍,需要的朋友参考下 组件的特点对于Android的四大组件Activity, Service, ContentProvider和Service,不能有Setter和Getter,也不能给组件添加接口.原因是组件都是给系统框架调用的,开发者只能实现其规定的回调接口,组件的创建与销毁都是由系统框架控制的,开发者不能强行干预,更没有办法获取组件的对象.比如Activity,Service,BroadcastReceiver

  • Ruby面向对象编程详解 2014-11-04

    这篇文章主要介绍了Ruby面向对象编程详解,本文讲解了类的定义.定义对象.initialize方法.实例变量.类变量.类常量.类的继承等内容,需要的朋友可以参考下 Ruby是纯面向对象的语言,所有项目似乎要Ruby中为一个对象.Ruby中的每个值是一个对象,即使是最原始的东西:字符串,数字甚至true和false.即使是一个类本身是一个对象,它是Class类的一个实例.本章将通过所有功能涉及到Ruby的面向对象. 类是用来指定对象的形式,它结合了数据表示和方法操纵这些数据,转换成一个整齐的包.在