本节内容:
引子
面向对象 v.s. 面向过程
面向对象编程介绍
面向对象的特性:
      封装
      继承
      多态
类、方法
 

1、引子

假设你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢?
你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色:
def person(name,age,sex,job):
    data = {
        'name':name,
        'age':age,
        'sex':sex,
        'job':job
    } 
    return data
 
def dog(name,dog_type):
    data = {
        'name':name,
        'type':dog_type
    }
    return data

上面两个方法相当于造了两个模子,游戏开始,你得生成一个人和狗的实际对象吧,怎么生成呢?

d1 = dog("李磊","京巴")
 
p1 = person("严帅",36,"F","运维")
 
p2 = person("林海峰",27,"F","Teacher")

两个角色对象生成了,狗和人还有不同的功能呀,狗会咬人,人会打狗,对不对? 怎么实现呢?想到了, 可以每个功能再写一个函数,想执行哪个功能,直接 调用 就可以了,对不?

def bark(d):
    print("dog %s:wang.wang..wang..."%d['name']) 
 
def walk(p):
    print("person %s is walking..." %p['name'])
d1 = dog("李磊","京巴")
p1 = person("严帅",36,"F","运维")
p2 = person("林海峰",27,"F","Teacher")

walk(p1) 
bark(d1)

但是仔细玩耍一会,你就不小心干了下面这件事:

p1 = person("严帅",36,"F","运维")
bark(p1)         # 把人的对象传给了狗的方法, 人家不干了

事实 上,这并没出错。很显然,人是不能调用狗的功能的,如何在代码级别实现这个限制呢?

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 def person(name, age, sex, job):
 6     def walk(p):
 7         print("person %s is walking..." % p['name'])
 8     data = {
 9         'name': name,
10         'age': age,
11         'sex': sex,
12         'job': job,
13         'walk': walk
14     }
15     return data
16 
17 
18 def dog(name, dog_type):
19     def bark(d):
20         print("dog %s:wang.wang..wang..." % d['name'])
21     data = {
22         'name': name,
23         'type': dog_type,
24         'bark': bark
25     }
26     return data
27 
28 d1 = dog("李磊","京巴")
29 p1 = person("严帅",36,"F","运维")
30 p2 = person("林海峰",27,"F","Teacher")
31 
32 d1['bark'](p1)        # 把人这个对象传给了狗
View Code

你是如此的机智,这样就实现了限制人只能用人自己的功能啦。

但,我的哥,不要高兴太早,刚才你只是阻止了两个完全 不同的角色 之前的功能混用, 但有没有可能 ,同一个种角色,但有些属性是不同的呢? 比如 ,大家都打过cs吧,cs里有警察和恐怖份子,但因为都 是人, 所以你写一个角色叫 person(), 警察和恐怖份子都 可以 互相射击,但警察不可以杀人质,恐怖分子可以,这怎么实现呢? 你想了说想,说,简单,只需要在杀人质的功能里加个判断,如果是警察,就不让杀不就ok了么。 没错, 这虽然 解决了杀人质的问题,但其实你会发现,警察和恐怖分子的区别还有很多,同时又有很多共性,如果 在每个区别处都 单独做判断,那得累死。 

你想了想说, 那就直接写2个角色吧, 反正 这么多区别, 我的哥, 不能写两个角色呀,因为他们还有很多共性 , 写两个不同的角色,就代表 相同的功能 也要重写了,是不是我的哥? 。。。

好了, 话题就给你点到这, 再多说你的智商 也理解不了了!

 

2、面向对象 v.s. 面向过程

编程范式

编程是 程序 员 用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式,当然也有些语言可以同时支持多种编程范式。 两种最重要的编程范式分别是面向过程编程和面向对象编程。

面向过程编程(Procedural Programming)
Procedural programming uses a list of instructions to tell the computer what to do step-by-step.
面向过程编程依赖 - 你猜到了- procedures,一个procedure包含一组要被进行计算的步骤, 面向过程又被称为top-down languages, 就是程序从上到下一步步执行,一步步从上到下,从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。

举个典型的面向过程的例子, 数据库备份, 分三步,连接数据库,备份数据库,测试备份文件可用性。

代码如下:

def db_conn():
    print("connecting db...") 
 
def db_backup(dbname):
    print("导出数据库...",dbname)
    print("将备份文件打包,移至相应目录...")
 
def db_backup_test():
    print("将备份文件导入测试库,看导入是否成功") 
 
def main():
    db_conn()
    db_backup('my_db')
    db_backup_test()  
 
if __name__ == '__main__':
    main()

这样做的问题也是显而易见的,就是如果你要对程序进行修改,对你修改的那部分有依赖的各个部分你都也要跟着修改, 举个例子,如果程序开头你设置了一个变量值为1 , 但如果其它子过程依赖这个值为1的变量才能正常运行,那如果你改了这个变量,那这个子过程你也要修改,假如又有一个其它子程序依赖这个子过程,那就会发生一连串的影响,随着程序越来越大, 这种编程方式的维护难度会越来越高。
所以我们一般认为, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,但如果你要处理的任务是复杂的,且需要不断迭代和维护 的, 那还是用面向对象最方便了。

相关文章:

  • 2022-01-06
  • 2021-09-26
  • 2021-11-18
猜你喜欢
  • 2021-05-29
  • 2022-01-16
  • 2021-09-11
  • 2021-08-30
相关资源
相似解决方案