标签:
面向对象编程需要类和对象来实现,其实就是对类和对象的使用。
类是什么?
类就是一个模版,模版里包含多个函数,函数里实现一些功能。
对象是什么?
对象则是根据模版创建的实例,通过实例对象可以执行类中的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo: # 创建类中的函数 def Bar( self ): print "Bar" def Hello( self ,name): print ‘I am %s‘ % name # 根据类Foo创建obj obj = Foo() # 执行Bar方法 obj.Bar() # 执行Hello方法 obj.Hello( ‘caoxiaojian‘ ) |
函数是式的应用场景:各个函数之间是独立的且无共用的数据。
三大特性是:封装性、继承性、多态性。
含义:就是将内容封装到某个地方,以后再去调用倍封装在某处的内容
使用方式:
#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo: def __init__(self,name,age): #称为构造方法,根据类创建对象时自动执行 self.name = name self.age = age # 根据类Foo创建对象obj1 # 自动执行Foo类的 __init__方法 obj1 = Foo(‘caoxiaojian‘,‘24‘) # 将caoxiaojian和24分别封装到obj1(self)的name和age属性中 # 根据类Foo创建对象obj2 # 自动执行Foo类的 __init__方法 obj2 = Foo(‘caogaotian‘,‘23‘) # 将caogoatian和23分别封装到obj2(self)的name和age属性中
self是一个形式参数,当执行obj1 = Foo(‘caoxiaojian‘,‘24‘)时,self等于obj1,同理执行obj2的时候,self等于obj2。所以,内容其实被封装到了对象obj1和obj2中,每个对象中都有name和age属性,在内存中保存下来
B:从某处调用被封装的内容
调用被封装的内容时,有两种情况:
1:通过对象直接调用
上图展示了对象obj1和obj2在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象名.属性名
#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo: def __init__(self,name,age): #称为构造方法,根据类创建对象时自动执行 self.name = name self.age = age # 根据类Foo创建对象obj1 # 自动执行Foo类的 __init__方法 obj1 = Foo(‘caoxiaojian‘,‘24‘) # 将caoxiaojian和24分别封装到obj1(self)的name和age属性中 print obj1.name # 直接调用obj1对象的name属性 print obj1.age # 直接调用obj1对象的age属性 # 根据类Foo创建对象obj2 # 自动执行Foo类的 __init__方法 obj2 = Foo(‘caogaotian‘,‘23‘) # 将caogoatian和23分别封装到obj2(self)的name和age属性中 print obj2.name # 直接调用obj2对象的name属性 print obj2.age # 直接调用obj2对象的age属性
2:通过self间接调用被封装的内容
执行类中方法时,需要通过self间接调用被封装的内容
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
|
#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo: def __init__( self ,name,age): #称为构造方法,根据类创建对象时自动执行 self .name = name self .age = age def detail( self ): print self .name print self .age # 根据类Foo创建对象 # 自动执行Foo类的__init__方法 obj1 = Foo( ‘caoxiaojian‘ , 23 ) obj1.detail() ‘‘‘ python默认会将obj1传给self参数,即obj1.detail(obj1), 所以此时方法内部的self = obj1, 即:self.name是caoxiaojian;self.age是23 ‘‘‘ obj2 = Foo( ‘caogaotian‘ , 24 ) obj2.detail() # 打印结果: # caoxiaojian # 23 # caogaotian # 24 |
总结:
对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self方式间接获取被封装的被内容。
练习一:
函数式编程方式:
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
|
#!/usr/bin/env python # coding:utf-8 # python def python(name,age,sex): print "%s,%s岁,%s,上老男孩python培训" % (name,age,sex) def base(name,age,sex): print "%s,%s岁,%s,上老男孩基础运维培训" % (name,age,sex) def high(name,age,sex): print "%s,%s岁,%s,上老男孩架构师培训" % (name,age,sex) python( ‘曹小贱‘ , 23 , ‘男‘ ) base( ‘曹小贱‘ , 23 , ‘男‘ ) high( ‘曹小贱‘ , 23 , ‘男‘ ) python( ‘曹高田‘ , 23 , ‘男‘ ) base( ‘曹高田‘ , 23 , ‘男‘ ) high( ‘曹高田‘ , 23 , ‘男‘ ) ‘‘‘ 执行结果: 曹小贱,23岁,男,上老男孩python培训 曹小贱,23岁,男,上老男孩基础运维培训 曹小贱,23岁,男,上老男孩架构师培训 曹高田,23岁,男,上老男孩python培训 曹高田,23岁,男,上老男孩基础运维培训 曹高田,23岁,男,上老男孩架构师培训 ‘‘‘ |
面向对象编程方式:
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
|
#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo: def __init__( self ,name,age,sex): #称为构造方法,根据类创建对象时自动执行 self .name = name self .age = age self .sex = sex def python( self ): print "%s,%s岁,%s,上老男孩python培训" % ( self .name, self .age, self .sex) def base( self ): print "%s,%s岁,%s,上老男孩base培训" % ( self .name, self .age, self .sex) def high( self ): print "%s,%s岁,%s,上老男孩架构师培训" % ( self .name, self .age, self .sex) # 根据类Foo创建对象caoxiaojian # 自动执行Foo类的 __init__方法 caoxiaojian = Foo( ‘曹小贱‘ , 23 , ‘男‘ ) caoxiaojian.python() caoxiaojian.base() caoxiaojian.high() caogaotian = Foo( ‘曹高田‘ , 24 , ‘男‘ ) caogaotian.python() caogaotian.base() caogaotian.high() ‘‘‘ 打印结果: 曹小贱,23岁,男,上老男孩python培训 曹小贱,23岁,男,上老男孩base培训 曹小贱,23岁,男,上老男孩架构师培训 曹高田,24岁,男,上老男孩python培训 曹高田,24岁,男,上老男孩base培训 曹高田,24岁,男,上老男孩架构师培训 ‘‘‘ |
总结:
如果使用函数式编程,需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了。。。;而对于面向对象只需要在创建对象时,将所有的参数封装到当前的对象中,之后再次使用时,通过self间接去当前对象中取值即可
继承:子可以继承父的内容
例如:
动物:吃、喝、拉、撒
猫:吃(继承动物的功能)
狗:喝(继承动物的功能)
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
41
42
43
44
45
46
47
48
|
#!/usr/bin/env python # coding:utf-8 # 创建动物类 class animal: def eat( self ): print "%s 吃吃吃" % self .name def drink( self ): print "%s 喝喝喝" % self .name def shit( self ): print "%s 拉拉拉" % self .name def pee( self ): print "%s 撒撒撒" % self .name # 创建猫类 class cat(animal): def __init__( self ,name): self .name = name self .bread = ‘猫‘ def cry( self ): print "喵喵喵喵喵喵喵喵" class dog(animal): def __init__( self ,name): self .name = name self .bread = ‘狗‘ def cry( self ): print "汪汪汪汪汪汪汪汪汪汪汪汪" # 根据类cat创建对象obj1 # 自动执行cat类的 __init__方法 obj1 = cat( ‘小花猫‘ ) obj1.eat() obj1.cry() obj2 = cat( ‘黑猫警长‘ ) obj2.drink() obj2.cry() obj3 = dog( ‘哈士奇‘ ) obj3.shit() obj3.cry() ‘‘‘ 打印结果: 小花猫 吃吃吃 喵喵喵喵喵喵喵喵 黑猫警长 喝喝喝 喵喵喵喵喵喵喵喵 哈士奇 拉拉拉 汪汪汪汪汪汪汪汪汪汪汪汪 ‘‘‘ |
总结:
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需要继承父类而不必一一实现每一个方法。
多继承???
1:Python的类可以继承多个类,Java和C#中则只能继承一个类
2:Python的类如果继承多个类,那么其寻找方法的方式有两种:深度优先和广度优先
经典类和新式类区别:当前类或者父类继承了object类,那么该类便是新式类,否则就是经典类
实例一:经典类
#!/usr/bin/env python # coding:utf-8 class D: def bar(self): print ‘D.bar‘ class C(D): def bar(self): print ‘C.bar‘ class B(D): def bar(self): print ‘B.bar‘ class A(B, C): def bar(self): print ‘A.bar‘ a = A() a.bar() # 打印结果:A.bar
总结:
1:执行bar方法时首先去A类中找,如果A类中没有,则去B类中找,如果没有,再去D类中找,如果没有,再去C类中找,如果找不到,则报错
2:查找的顺序:A===>B===>D===>C
3:一旦找到,则寻找过程立即中断,不再继续寻找
实例二:新式类
#!/usr/bin/env python # coding:utf-8 class D(object): def bar(self): print ‘D.bar‘ class C(D): def bar(self): print ‘C.bar‘ class B(D): def bar(self): print ‘B.bar‘ class A(B, C): def bar(self): print ‘A.bar‘ a = A() a.bar() # 打印结果:A.bar
总结:
1:执行bar方法时首先去A类中找,如果A类中没有,则去B类中找,如果没有,再去C类中找,如果没有,再去D类中找,如果找不到,则报错
2:查找的顺序:A===>B===>C===>D
3:一旦找到,则寻找过程立即中断,不再继续寻找
python不支持多态并且也用不到多态,多态的概念是应用于Java和C#这类强类型语言中,而Python崇尚“鸭子类型”
鸭子类型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/env python # coding:utf-8 class F1: pass class S1(F1): def show( self ): print ‘S1.show‘ class S2(F1): def show( self ): print ‘S2.show‘ def Func(obj): print obj.show() s1_obj = S1() Func(s1_obj) s2_obj = S2() Func(s2_obj) |
标签:
原文地址:http://www.cnblogs.com/kevingrace/p/5569938.html