面向对象第一节——面向对象思想

大自然是面向对象方法最早的发明者,也是面向对象规则最熟练的使用者,我们程序设计中面向对象的理念,方法和思想,皆是对我们生活的这个现实社会的抽象。

说到面向对象,自然会提起面向过程,关于两者之间关系的讨论几乎是所有教科书的必选动作,这里,我不想用一大堆文字去解释它们的联系与区别,只想用一个例子来直观的告诉大家两者最明显的区别。当然,所有的比喻都背离了事物的本质,即使比喻用的足够形象。比喻的目的是为了帮助理解,展开想象,而不是复原事物自身。

首先,我们必须明确一点:所有程序设计的目的,都是为了解决我们现实中遇到的问题。

好,假如我们现在面临这样一个问题:要吃饺子。

从面相过程的思维出发,这个问题应该这样解决:我们要去超市买做饺子需要的食材,买饺子皮,饺子馅,各种需要的佐料等,然后我们再回家自己包饺子,然后煮熟就可以吃了。

从面相对象的思维出发,这个问题应该这样解决:我们去超市直接买做好的饺子,你只需要选择自己喜欢的口味就可以了,至于其他的东西,你不用管,有人都给你做好了,回家后直接煮了吃就OK

当然,这只是为了直观的给大家一个面向对象和面向过程概念的区别,如果追究其细节,自然也有很多不合理的地方。但对于理解这两种思想的差别,这个比喻足够了。

搞清楚了面向过程和面向对象的区别,我们再来说说面向对象的几个特征。

第一个特征:抽象。

刚才也说了,程序设计中面向对象的理念,方法和思想,皆是对我们生活的这个现实社会的抽象。

抽象这个词,确实抽象,不好描述。有点只可意会,不可言传的感觉。面向对象中的抽象,其实是一种对特点特征的提炼,然后统一出一个模型,在面向对象程序设计语言中,这个模型有个专门的名称:类。类有自己的名字,叫类名。举个例子,假如你在面向对象设计中需要这样一种神兽:两条腿,两个胳膊,能直立行走,能说话,没有尾巴。好,你提炼出你需要的模型具备这几个特点,那你完全可以把这几个特点放在一起,并且给这种神兽起个名字:人类。抽象出类之后,接下来要做的就是封装这些特征,这也正是面向对象的第二个特征,封装。

第二个特征:封装。

所谓的封装,可以理解成打包,拿饺子的例子来说,本来你如果自己做饺子的时候,饺子馅是完全可以看到的。但是如果从超市买,由于饺子皮把馅全部包住了,你就看不到饺子馅了。饺子皮对饺子馅进行了封装。那谁能看到超市的饺子的饺子馅到底是不是正宗呢?生产饺子的厂家,为什么他们能看到?因为权限不同。好,不往深处说了,太多了容易乱。面向对象中怎样来区分权限?很简单:public  protected  private 等关键词就可以搞定。

那封装有什么好处?

第一点:安全。没有权利的,想乱动都动不了。

第二点:便于复用(重复利用)。这个后面再详细介绍。

 

第三个特征:继承。

继承的概念和人类社会,生物社会的继承有大致相同的意思,但有一些区别。继承,顾名思义,就是承接之前的东西。那大自然是怎样实现继承这个概念的呢?繁殖!子又生孙,孙又生子,子子孙孙无穷匮也!当然,面向对象的继承没有生物社会特别是人类社会这样充满感情,在面向对象设计中,继承很简单,关键字extends搞定。继承后的类型应该是一个新的类型(当然,你也完全可以什么都不添加,使其和它所继承的类(父类)完全相同,但那样就失去了继承的意义)为了使其与父类不同,你需要给新类添加新东西,新功能。这点,很容易做到,添加一个方法,或者添加一个字段就ok了。

继承的最大好处:复用。

继承后导致的一个问题是,如果一个父类被不同的子类继承了,比如,我们有一个类animal.然后animal有一个功能是 会叫。然后我们有不同的三个类去继承它,分别是dogcat sheep。当我们继承了animal之后,这三个子类自然也获得了"会叫”这个功能,但是,不同的子类叫声是不一样的,dog应该是“汪汪”,cat应该是“喵喵”,sheep应该是“咩咩”。那怎样保证你在使用它们会叫的功能时保证它们发出自己应有的声音呢?多态!这就是面向对象程序设计中的“多态”,也是面向对象程序设计的第四个特征。

 

第四个特征:多态。

多态,表面上看就是多种形态。恩,有时候从字面意思理解一些东西反而很有收获,我刚开始接触多态的时候,很难理解其意思,更不用说其机制了。后来理解了多种形态之后,才算看到了庐山真面目的一角。正如刚才说的,如何保证不同的动物发出自己该发出的声音,这正是面向对象程序设计中多态特性的应用。和多态伴随的,是向上转型,当然,也有向下转型,但向下转型有时候是不安全的,需要条件。好,不多说,太多了又乱。

 

抽象,封装,继承和多态,被认为是面向对象程序设计的四个基本特征,当然,很多资料也说是三个,即封装,继承和多态。不把抽象作为一个特征是因为抽象这个过程比较隐蔽,你在不知不觉中已经对你需要的模型作了抽象,不论三个还是四个,你自己理解就可以了。

这里面还有一组比较重要的概念是 继承和组合。那这两者有什么区别呢?

首先,我们得明白,继承来的东西,肯定有原来父类的秉性,即从类上来说,它们至少是一个祖先或者具有近亲关系,而组合而来的东西,就不一定了,可以随意了,也正是因为组合的这个特点,使得面向对象程序设计有了更好的灵活性。(比如java中继承只支持单继承,组合给了java更大的自由)

继承和组合到底如何区分?看下面的一个例子。

如果我想要一个带有闹铃功能的闹钟。首先,我们用面向对象的思想先抽象一下这个物品。带有闹铃功能的闹钟。首先,这是一个钟表,也就是需要抽象一个钟表类,这个类至少应该有一个功能:显示时间。然后呢,还得有一个闹铃类,这个类至少得有一个功能:发出声音。

好了,我们有了钟表类,有了闹铃类,那我们怎样得到一个有闹铃功能的钟表呢?答案:组合!把它俩组合起来,功能就全了。

那为什么不是继承呢?因为它们不是一个类,钟表和闹铃的关系是八竿子打不着的。(或许有的人觉得它俩天生一对,那是因为你对我们生活的这个世界太熟悉了,对现实中的事物都觉得理所当然了,你仔细想想,一个主要功能是为了显示时间,一个主要功能是为了发出声音,这两个东西能是一个种类吗?)但是,人类用组合的方式使两者结合在了一起,而且配合的天衣无缝,感觉是一个闹钟类。(当然可以构造这样的类,但是这里为了说明组合和继承的区别,分的更细化了,类的设计是自由的,这里是为了说明问题)

那什么时候使用继承?什么时候组合?

如果这样的一句话是合理的,则可以使用继承,即a是一种A。比如,麻雀是一种鸟,那么继承。

如果这样的一句话是不合理的,则考虑组合。a是一种A,不合理。比如,狮虎兽(老虎和狮子生育的后代)是一种老虎,不合理吧,狮虎兽是一种狮子,不合理吧,则组合。狮虎兽是狮子和老虎的组合,即它既具有狮子的特点,又具有老虎的特点。

关于继承和组合的区别,说的不够形象,以后想到好的例子再告诉大家吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值