Python 学习笔记 - 面向对象(封装,继承和多态)


之前学习的编程方式都是通过面向过程来实现的,对于一些重用的代码,进一步的使用了函数,增强了代码的可读性和重用性。Python同时还支持面向对象的编程。


面向对象有三大特性:

  1. 封装

  2. 继承

  3. 多态


首先来看看封装。封装包括两点,把内容封装到某个地方;调用封装的内容


例1;


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
class  c1:
     def  __init__( self ,name,obj):
         self .name  =  name
         self .obj  =  obj
class  c2:
     def  __init__( self ,name,age):
         self .name  =  name
         self .age  =  age
     def  show( self ):
         print ( self .name)
         return  123
class  c3:
     def  __init__( self , a1):
         self .money  =  123
         self .aaa  =  a1
c2_obj  =  c2( 'aa' 11 )
# c2_obj是c2类型
# - name = "aa"
# - age = 11
c1_obj  =  c1( "alex" , c2_obj)
# c1_obj 是c1 类型
# - name = "alex"
# - obj = c2_obj
c3_obj  =  c3(c1_obj)
# 使用c3_obj执行show方法
ret  =  c3_obj.aaa.obj.show()
print (ret)
print (c3_obj.money)
- - - - - - - - -
aa
123
123

几个注意事项:

  • 我定义了3个类,每个类都有自己的构造方法__init__,我对每一个类都进行实例化一个对象;每个对象创建的时候会自动调用自己的__init__方法封装不同的内容;

  • self是一个形式参数,他就相当于实例,比如当c1_obj=c1('alex',c2_obj),self就等于c1_obj

  • 当我们输出money这个字段的时候,c3_obj可以调用show这个方法输出money(间接调用self)或者直接输出c3_obj.money(直接调用)

  • 对象本身也可以当做参数传给其他的类



封装的概念有了,如果还记得前面学的pickle,我们可以把自定义的结构序列化保存到一个文件中。

s1.py

1
2
3
4
5
6
7
8
class  Foo:
     def  __init__( self , name):
         self .name  =  name
     def  show( self ):
         print ( self .name)
import  pickle
obj  =  Foo( 'alex' )
pickle.dump(obj,  open ( 'db' , 'wb' ))


如果在另外一个文件里面调用这个pickle序列化的文件,必须导入对应的类,不然无法识别

s2.py

1
2
3
4
5
6
import  pickle
from  s1  import  Foo
ret  =  pickle.load( open ( 'db' , 'rb' ))
print (ret)
- - - - - - - - - - - - - - -
<s1.Foo  object  at  0x000001E5F421BEB8 >



接下来看看继承,子类可以继承父类的所有东西。


首先看看单继承的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class  F1:  # 父类,基类
     def  show( self ):
         print ( 'show' )
     def  foo( self ):
         print ( self .name)
class  F2(F1):  # 子类,派生类
     def  __init__( self , name):
         self .name  =  name
     def  bar( self ):
         print ( 'bar' )
     def  show( self ):
         print ( 'F2.show' )
obj  =  F2( 'alex' )
obj.show()
obj.foo()
- - - - - - - - -
F2.show
alex

注意要点:

  • F2是F1的子类

  • 创建obj对象的时候,他自动调用F2的构造函数,当他尝试调用foo()方法的时候,首先看自己有没有,如果没有就去父类寻找。类似的,当调用show()的时候,因为自己已经有了,因此直接调用自己的



看看另外一个例子,原理一样,子类的对象调用方法的时候,self是指向的子类对象,因此他的顺序始终是从子类开始寻找的,找不到才去父类找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class  S1:
     def  F1( self ):
         self .F2()
     def  F2( self ):
         print ( "S1.f2" )
class  S2(S1):
     def  F3( self ):
         self .F1()
     def  F2( self ):
         print ( "S2.f2" )
obj  =  S2()
obj.F3()
obj  =  S1()
obj.F1()
- - - - - - - - - - - - -
S2.f2
S1.f2


接下来看看python特有的多继承,格式很简单C1(C2,C3)表示C1同时继承C2和C3

当多继承的类里面进行调用的时候,遵循的原则有2点,如果是下图左边的情景,那么先在左边做完深度遍历再去找右边的父类;如果是右边的情景,有共同的祖先,那么通过左边到祖先的下面,然后通过右边的父类直到祖先


wKiom1fvQP2jqq0lAABVvzUV2Ng304.png


例如,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class  C_2:
     def  f2( self ):
         print ( 'C-2' )
class  C_1(C_2):
     def  f12( self ):
         print ( 'C-1' )
class  C0(C_2):
     def  f2( self ):
         print ( 'C0' )
class  C1(C0):
     def  f1( self ):
         print ( 'C1' )
class  C2(C_1):
     def  f12( self ):
         print ( 'C2' )
class  C3(C1,C2):
     def  f3( self ):
         pass
obj  =  C3()
obj.f2()
- - - - -
C0



最后看看多态。Python里面原生态的支持多态,比如传入参数的时候不需要指定类型,可以是任何数据类型;而类似的方式在Java或者C#里面需要通过继承来实现同一方法传入不同数据类型的参数



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)
- - - - - - - - - - - - -
S1.show
None
S2.show
None

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值