Python-面向对象编程
概述:
- 面向过程:根据业务逻辑从上到下写代码。
- 函数式:将某功能代码封装到函数中,以后便无需重复编写,进调用函数即可。
- 面向对象:对函数进行分类和封装,让开发“更快更好更强”
创建类和对象
面向对象编程需要类和对象来实现,其实就是对类和对象的使用。
类是什么?
类就是一个模版,模版里包含多个函数,函数里实现一些功能。
对象是什么?
对象则是根据模版创建的实例,通过实例对象可以执行类中的函数
- class是关键字,表示类
- 创建对象,类名称后加括号就是创建对象
- 类中的函数第一个参数必须是self(是函数三大特性之一封装性)
- 类中定义的函数叫方法
|
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'
)
|
- 面向对象:【创建对象】==【通过对象执行方法】
- 函数编程:【执行函数】
函数是式的应用场景:各个函数之间是独立的且无共用的数据。
面向对象的三大特性
三大特性是:封装性、继承性、多态性。
一:封装
含义:就是将内容封装到某个地方,以后再去调用倍封装在某处的内容
使用方式:
- 将内容封装到某处
- 从某处调用被封装的内容
A:将内容封装到某处
#!/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方式间接获取被封装的被内容。
练习一:
- 曹小贱,10岁,男,上老男孩python培训
- 曹小贱,10岁,男,上老男孩基础运维培训
- 曹小贱,10岁,男,上老男孩架构师培训
- 曹高田,10岁,男,上老男孩python培训
- 曹高田,10岁,男,上老男孩基础运维培训
- 曹高田,10岁,男,上老男孩架构师培训
函数式编程方式:
|
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)
|




![9GVPI}TWE]4YU0`Y}4~A_SY 9GVPI}TWE]4YU0`Y}4~A_SY](https://images2015.cnblogs.com/blog/827552/201512/827552-20151205003028877-300010788.png)

