LVOOP(二)

        本篇章详解面向对象的三大要素以及建立抽象层。

在这里先说点题外话,编程语言的历史,感兴趣的可以看看。

        计算机只可以解释用二进制数编写的机器语言。并且,计算机对机器语言不进行任何检查,只是飞快地执行。所以计算机诞生初期,是使用的机器语言进行编程。人类无法识别机器语言,不明白下面这样的一段程序实现了什么功能。

A10010
8B160210
01D0
A10410

        为了改善这种低效的编程,汇编语言应运而生。汇编语言将无含义的机器语言用人类容易理解的符号表示出来。将上面的代码用汇编语言写出来的话,如下所示。除非是专业人士,否则也很难理解这段代码。不过程序员一般都知道,MOV是发送信息的意思,ADD是加法运算。汇编语言是编程语言的第一步。使用汇编语言编写的程序被读入对其进行编译的其他程序(称为汇编程序)中,从而生成机器语言。不过,在使用汇编语言编写的程序中,即使命令存在一点点错误也会导致程序运行异常。另外,虽然汇编语言容易理解,但是在编程时逐个指定计算机的执行命令是非常麻烦的。

MOV   AX, X
MOV   DX, Y
ADD   AX, DX
MOV   Z, AX

        随后,用更贴近人类语言的表达形式来编写程序高级语言被发明出来。高级语言并不是逐个编写能让计算机理解的命令,而是采用人类更容易理解的“高级”形式。对比上面两段代码,我们会发现高级语言的便捷性是非常明显的。下面的代码与数学计算公式非常相似,因此即使是完全没有编程经验的人也能理解。这种高级语言在计算机刚出现不久的20世纪50年代前半期被设计出来。

Z=X+Y

        在20世纪60年代后半期NATO召开的一次国际会议上提出了所谓的软件危机——20世纪末,即使全人类都成为程序员,也无法满足日益增长的软件需求。为了应对软件危机,人们提出了各种新的思想和编程语言。
        其中,最受关注的就是结构化编程

        结构化编程由荷兰计算机科学家戴克斯特拉(Dijkstra)提出,其基本思想是:为了编写出能够正确运行的程序,采用简单易懂的结构是非常重要的。具体方法就是废除程序中难以理解的GOTO语句,提倡只使用循序、选择和重复这三种结构来表达逻辑。也就是顺序、条件和循环。

        不过,结构化编程有两个无法解决的问题,那就是全局变量问题和可重用性差的问题。

        全局变量可以被程序的任何位置使用,所以当因某种情况而需要修改全局变量时,为了查明影响范围,就必须调查所有的逻辑。如果程序很大,那么这种由全局变量引发的问题就会非常严重,这是结构化语言中很难避免的问题。

        另一个问题是可重用性差。结构化语言中可重用的是子程序,而现在已经有了用于编码转换、输入/输出处理、数值计算和字符串处理等的通用库,通过重用既有程序就可以在一定程度上实现基本的处理。然而即便如此,从不断增大的应用程序的整体规模来看,效果只能说是微不足道的。
因此需要提高可重用的规模,这已经成为软件开发者的共识,但这一点却很难实现,主要原因就在于作为公用构件创建的只是子程序。
        而能够打破该限制的正是OOP。

面向对象的三大要素:封装、继承、多态

封装

         把数据和行为封装到单个对象中是面向对象开发中的重中之重。单个对象既包含自身的数据,也包含自身的行为,并且可以向其他对象隐藏自身的某些东西。

        封装即是隐藏信息。上篇说到一个对象包含属性和行为(方法),为了保证高内聚低耦合,类的属性一般是私有数据,想要拿到这个数据需要通过他的方法进行调用

        比如,小明和小红是两个类,他们继承于同一个类,人类。他们具备相同的属性和方法,属性(姓名,年龄),方法(获取姓名,获取年龄)。姓名和年龄是私有的,当小红(外界)想知道小明的年龄时,只能通过方法(获取年龄)对小明进行发问“你今年几岁了?”来得到这个属性。

        而年龄涉及计算,当前年减去出生年才是年龄,但这个计算过程是私有的,也就是被封装的,只留下最终结果。以编程的思维来思考,这个计算年龄的过程,也就是实现程序的过程,是被程序员隐藏的,不可更改的。我们只需要留下一个接口(年龄),来通过方法调用。当然也可以不留接口,那就是完全隐藏的,接口最小化原则(将所有的东西都封装,直到客户提出需要再创建接口)

        封装有很多优点,我们可以在不影响功能的实现(获取年龄)去修改年龄的计算过程(新增月份天数等),用户并没有感觉到什么变化,小红依然只需要询问小明“你今年几岁了?”这个方法来调用,但其实我们已经对实现的过程进行改进了。在调试过程中也可以很好的发现问题出在哪,因为高内聚,只要年龄这个结果不对,那么我们就知道了是年龄的计算过程有问题,进行修改即可。也可以很好的保护私有数据不被其他程序员随意修改。

继承

        一个类可以继承另一个类,并且可以使用父类中定义的属性和方法。

        在封装里有提到,小明和小红继承于人类,因为小明和小红都人类。判断能不能继承抽象类的最简单的方法就是(他是不是某某某)。比如麻雀和鹦鹉都是鸟,银渐层和金渐层都是猫,哈士奇和泰迪都是狗。

        因为小明和小红继承于人类,所以他们都可以使用人类定义的属性和方法。所以小明和小红都有姓名和年龄,以及获取姓名获取年龄的方法。如果人类定义了新的属性和方法,比如属性(眼睛颜色),方法(获取眼睛颜色),那么小明和小红也能够拥有和调用。

        在项目编程中,为了去除类的重复定义,我们通常会创建一个抽象层,使其具备公有的属性和方法,子类继承这个抽象层。如果不创建抽象层,比如不创建人类,那么就需要单独为小明,小红创建重复的属性和方法,姓名、年龄......这是很繁杂和低效的。

        当然除了继承下来的公有属性和方法,小明和小红也可以有自己独有的属性和方法。比如小明可以有数学天赋,小红可以有歌唱天赋等。这样每次新增加一个实例,我们就不需要再去定义那些公有的属性和方法,只需要定义其独有的即可。

多态

        多态性意味着相似的对象对相同的消息有着不同的响应。多态的前提是不同的实例继承于同一个父类。

       小明和小红都继承于人类, 对小明和小红两个类发送同样的消息去调用方法获取年龄,可以得到不同的响应,小明12岁,小红10岁。

抽象

        之前有说到要建立抽象层,这个根据个人理解的不同创建有所不同,小红和小明,他们的抽象层可以是人类,也可以是动物,也可以是哺乳动物。抽象是一种概念。抽象层次越高,具体信息越少,但是概括能力越强;反之,具体信息越丰富,结果越确定。比如动物的层次就比哺乳动物高,因为动物攘括了哺乳动物,而哺乳动物又攘括了人。人就已经很具体了,但也可以更具体,青少年,等等等等。在实际项目开发中根据自己的需求去建立抽象层。

        当同一个方法,你希望在不同实例中以不同的形式实现,那么就可以在抽象层中建立抽象方法。人类具有一个抽象方法,做一顿饭。这个方法没有写具体的实现过程,那么当小明和小红继承这个抽象方法时,就需要对这个方法进行重写。小明可以先烧水,再摘菜,再淘米等等。小红可以先炒菜,再煮饭等等。根据实现的过程不同那最终得到不同的结果。在项目中那就是根据想要得到的结果去设计过程。

        如果没有这种需求就可以在人类中写好具体的实现方法,那么小明和小红不需要再重写,直接调用就可以得到一顿做好的相同的饭。

        在编程中,比如两个不同的实例都需要初始化,一个需要初始化为0,一个需要初始化为1,那么就可以在他们的父类建立一个抽象方法(初始化),然后在两个实例中进行重写,一个置为0,一个置为1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白小白—

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值