day7 面向对象编程
Posted 屌丝爱篮球
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了day7 面向对象编程相关的知识,希望对你有一定的参考价值。
编程范式
编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式,当然也有些语言可以同时支持多种编程范式。 两种最重要的编程范式分别是面向过程编程和面向对象编程
面向过程编程
面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。程序从上到下一步步执行,一步步从上到下,从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。这样做的问题也是显而易见的,就是如果你要对程序进行修改,对你修改的那部分有依赖的各个部分你都也要跟着修改, 随着程序越来越大, 这种编程方式的维护难度会越来越高。 所以我们一般认为, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,但如果你要处理的任务是复杂的,且需要不断迭代和维护的, 那还是用面向对象最方便了。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#面向过程编程 while True : if cpu利用率 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 |
函数式编程
将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
示例:
练习:在终端输出如下信息 小明,10岁,男,上山去砍柴 小明,10岁,男,开车去东北 小明,10岁,男,最爱大保健 老李,90岁,男,上山去砍柴 老李,90岁,男,开车去东北 老李,90岁,男,最爱大保健
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #函数式编程 def firewood(name, age, gender): print ( "%s,%s岁,%s,上山去砍柴" % (name, age, gender)) def drive(name, age, gender): print ( "%s,%s岁,%s,开车去东北" % (name, age, gender)) def dbj(name, age, gender): print ( "%s,%s岁,%s,最爱大保健" % (name, age, gender)) firewood( \'小明\' , 10 , \'男\' ) drive( \'小明\' , 10 , \'男\' ) dbj( \'小明\' , 10 , \'男\' ) #小明,10岁,男,上山去砍柴 #小明,10岁,男,开车去东北 #小明,10岁,男,最爱大保健 firewood( \'老李\' , 90 , \'男\' ) drive( \'老李\' , 90 , \'男\' ) dbj( \'老李\' , 90 , \'男\' ) #老李,90岁,男,上山去砍柴 #老李,90岁,男,开车去东北 #老李,90岁,男,最爱大保健 |
面向对象编程
1、类、对象、实例
OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
示例:
练习:在终端输出如下信息 小明,10岁,男,上山去砍柴 小明,10岁,男,开车去东北 小明,10岁,男,最爱大保健 老李,90岁,男,上山去砍柴 老李,90岁,男,开车去东北 老李,90岁,男,最爱大保健
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #面向对象 class Foo: def __init__( self , name, age, gender): self .name = name self .age = age self .gender = gender def firewood( self ): print ( "%s,%s岁,%s,上山去砍柴" % ( self .name, self .age, self .gender)) def drive( self ): print ( "%s,%s岁,%s,开车去东北" % ( self .name, self .age, self .gender)) def dbj( self ): print ( "%s,%s岁,%s,最爱大保健" % ( self .name, self .age, self .gender)) xiaoming = Foo( \'小明\' , 10 , \'男\' ) xiaoming.firewood() xiaoming.drive() xiaoming.dbj() #小明,10岁,男,上山去砍柴 #小明,10岁,男,开车去东北 #小明,10岁,男,最爱大保健 laoli = Foo( \'老李\' , 90 , \'男\' ) laoli.firewood() laoli.drive() laoli.dbj() #老李,90岁,男,上山去砍柴 #老李,90岁,男,开车去东北 #老李,90岁,男,最爱大保健 |
面向对象编程的主要作用也是使你的代码修改和扩展变的更容易,那么小白要问了,既然函数都能实现这个需求了,还要OOP干毛线用呢? 呵呵,说这话就像,古时候,人们打仗杀人都用刀,后来出来了枪,它的主要功能跟刀一样,也是杀人,然后小白就问,既然刀能杀人了,那还要枪干毛线,哈哈,显而易见,因为枪能更好更快更容易的杀人。函数编程与OOP的主要区别就是OOP可以使程序更加容易扩展和易更改。
上面的程序做个简单认识即可,下面我们通过写一个cs程序来对面向对象编程做进一步认识
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #面向对象class class Role( object ): #定义一个类, class是定义类的语法,Role是类名,(object)是新式类的写法,暂且先记住 def __init__( self ,name,role,weapon,life_value = 100 ,money = 15000 ): #初始化函数,在生成一个角色时要初始化的一些属性就填写在这里 self .name = name #__init__中的第一个参数self为实例名称 self .role = role self .weapon = weapon self .life_value = life_value self .money = money #__init__()叫做初始化方法(或构造方法), 在类被调用时,这个方法(虽然它是函数形式,但在类中就不叫函数了, 叫方法)会自动执行, # 进行一些初始化的动作 def shot( self ): # 开了枪后要减子弹数 print ( "%s is shooting......." % ( self .name)) def got_shot( self ): # 中枪后要减血 print ( "ah.....%s:I got shot...." % ( self .name)) def buy_gun( self ,gun_name): # 检查钱够不够,买了枪后要扣钱 print ( "%s just bought %s " % ( self .name,gun_name)) #生成一个角色 , 会自动把参数传给Role下面的__init__(...)方法,这个过程叫做类的实例化,r1叫做类的实例 r1 = Role( \'Alex\' , \'police\' , "AK47" ) #此时self 相当于 r1 , Role(r1,\'Alex\',\'police\',\'AK47’) r2 = Role( \'Jack\' , \'terrorist\' , "B22" ) #此时self 相当于 r2 , Role(r2,\'Jack\',\'terrorist\',\'B22’) print (r1, type (r1)) print (r1.role) r1.shot() r1.got_shot() r1.buy_gun( "DZT100" ) # <__main__.Role object at 0x005A5BF0> <class \'__main__.Role\'> # police # Alex is shooting....... # ah.....Alex:I got shot.... # Alex just bought DZT100 |
2、类变量和实例变量
类变量为大家都共有的变量,只加载在类内存当中,不会加载在每个实例里;举个栗子:创建14亿用户,大家国籍都是中国,如果不把国籍写到类变量中,而是写到实例变量默认参数中,则14亿个实例,每个都要加载国籍到内存当中,会占用大量内存,这就是为什么我们要了解类变量的意义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#类变量和实例变量 class Role( object ): #定义一个类, class是定义类的语法 n = 123 #类变量 name = "类name" def __init__( self ,name,role,weapon,life_value = 100 ,money = 15000 ): self .name = name #实例变量 self .role = role self .weapon = weapon self .life_value = life_value self .money = money r1 = Role( \'Alex\' , \'police\' , "AK47" ) #实例 print (Role.n,r1.n) print (Role.name,r1.name) #123 123 #类name Alex |
由上面程序可知,类变量对全局生效,输入类名可直接调用;当类变量与实例变量相同且同时存在的话,实例变量优先
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#实例变量 class Role( object ): #定义一个类, class是定义类的语法 n = 123 #类变量 name = "类name" def __init__( self ,name,role,weapon,life_value = 100 ,money = 15000 ): self .name = name #实例变量 self .role = role self .weapon = weapon self .life_value = life_value self .money = money r1 = Role( \'Alex\' , \'police\' , "AK47" ) #实例 r1.name = "wupeiqi" r1.bullet = True print (r1.name,r1.bullet) #wupeiqi True |
类进行实例化之后,还可以对实例变量重新赋值、增加变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#类变量和实例变量 class Role( object ): #定义一个类, class是定义类的语法 n = 123 #类变量 name = "类name" def __init__( self ,name,role,weapon,life_value = 100 ,money = 15000 ): self .name = name #实例变量 self .role = role self .weapon = weapon self .life_value = life_value self .money = money r1 = Role( \'Alex\' , \'police\' , "AK47" ) #实例 r2 = Role( \'lzl\' , \'terrorist\' , \'B22\' ) r1.n = "r1的123" print (r1.name,r1.n) print (r2.name,r2.n) # Alex r1的123 # lzl 123 Role.n = "Role的123" print (r1.name,r1.n) print (r2.name,r2.n) # Alex r1的123 # lzl Role的123 |
执行上面的程序发现,赋值r1.n后只是影响到实例r1,对r2.n并没有任何影响,这是因为赋值的实例变量与类变量名一样时,并不会改变类变量中的值,只影响到当前实例;当重新赋值类变量时,r2也跟着改变;哈哈,此时你以为你都懂了,那让我们对上面的程序做个升级吧!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#类变量和实例变量 class Role( object ): #定义一个类, class是定义类的语法 list = [] #定义一个列表类变量 def __init__( self ,name,role,weapon,life_value = 100 ,money = 15000 ): self .name = name #实例变量 self .role = role self .weapon = weapon self .life_value = life_value self .money = money r1 = Role( \'Alex\' , \'police\' , "AK47" ) #实例 r2 = Role( \'lzl\' , \'terrorist\' , \'B22\' ) print (Role. list ) #此时list为空 #[] r1. list .append( "from r1" ) r2. list .append( "from r2" ) print (r1. list ) print (r2. list ) #[\'from r1\', \'from r2\'] # [\'from r1\', \'from r2\'] print (Role. list ) # [\'from r1\', \'from r2\'] |
从上面的程序可看出r1、r2改变了类变量;懒得解释了,自己理解吧O(∩_∩)O哈哈~
3、析构函数
在实例释放、销毁的时候执行,通常用于做一下收尾工作(如关闭数据连接)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|