Python攻克之路-类的继承、重写、方法调用和多态

1.类的特性之继承
描述:一个父类,一个子类,创建一个子类的对象,当它去调用方法时,先去子类中找是否有该方法,有就直接使用,没有就判断子类和父类是否有继承关系,有就去父类中找,找的只是方法,方法后面就是参数,相当于把那个东西直接使用执行就OK,所以self是谁调用它就是代指是谁

 [root@python3 day1]# cat inherit.py 
#!/usr/local/python3/bin/python3
class GrandFather:
    def swim(self)
class Father(GrandFather):        #父类,别名基类
    def basketball(self):
        pass
    def football(self):
        pass
    def smoke(self):
        pass
    def wine(self):
        pass
class Son(Father):    #子类,别名派生类,建立关联,继承了,父的所有方法都可以执行
    def reading(self):
        pass
s = son()
s.smoke()
s.reading()
s.swim()

  

2.重写:实现不继承某个些功能

[root@python3 day1]# cat class_test4.py 
#!/usr/local/python3/bin/python3
class F:
    def f1(self):
        print('F.f1')
    def f2(self):
        print('F.f2')
class S(F):
    def s1(self):
        print('S.s1')
obj = S()
obj.s1()
obj.f2()
[root@python3 day1]# python3 class_test4.py
S.s1
F.f2      ##默认是继承父的

[root@python3 day1]# cat class_test4.py
#!/usr/local/python3/bin/python3
class F:
    def f1(self):
        print('F.f1')
    def f2(self):
        print('F.f2')
class S(F):
    def s1(self):
        print('S.s1')
    def f2(self):          #自定义,就不会继承父的
        print('S.f2')
obj = S()
obj.s1()   #s1中的self是形参,此时代指obj
obj.f1()   #self是那个调用它,它就代指那个,这里的self还是f1,即使class S中没有
obj.f2()
[root@python3 day1]# python3 class_test4.py
S.s1
F.f1
S.f2

既有继承父类的,也执行自身的(super)
描述:主动去调用父类方法有两类使用super(推荐使用)和类名加方法

[root@python3 day1]# cat class_test4.py
#!/usr/local/python3/bin/python3
class F:
    def f1(self):
        print('F.f1')
    def f2(self):
        print('F.f2')
class S(F):
    def s1(self):
        print('S.s1')
    def f2(self):
        super(S,self).f2()  
#传两个参数,一个是自己(当前的类名),另一个是self,调用的对象,f2()是传要执行的方法,实际super是父类,所以整体意思是找到父类执行f2,
 也可以执行其它的方法
        #F.f2(self)  
        #是另一种方法,F指定的类名,点f2是执行f(),把self传入,这与原来的对象不一样,原来对象点f2时,self是自动传,这次是直接通过类
        名调用的方法,self要手动传,以前创建对象执行方法self是自动创建,这次的self要自己创建,因为执行f2时,父类的self是obj,所以要
        把obj传给它,
        print('S.f2')
obj = S()
obj.f2()
[root@python3 day1]# python3 class_test4.py
F.f2
S.f2

  

3.生产场景
有一个web框架,小程序,内部代码都已经写好了,创建一个类的对象,再执行以后的操作,已经有一个流程,现在需要添加一个功能,要使用开放封闭原则,不允许修改源码,可以扩展

class RequestHandler:
    def get(self,arg):
        print('get')
class BaseRequest(RequestHandler):  #增加一个扩展的类
    def mod(self,arg):
        print('mod')
obj = RequestHandler()
obj.get()

  

4.多继承
继承:子类可以有父类,父类可以再有父类,一般一个子只是继承一个父,但是python可以支持两个父类

[root@python3 day1]# cat class_test5.py
#!/usr/local/python3/bin/python3
class F1:
    def a(self):          ##定义两个类,相同的a的方法
        print('F1.a')
class F2:
    def a(self):
        print('F2.a')
class S(F1,F2):  ####
    pass
obj = S()
obj.a()
[root@python3 day1]# python3 class_test5.py
F1.a

[root@python3 day1]# cat class_test5.py
#!/usr/local/python3/bin/python3
class F1:
    def a(self):
        print('F1.a')
class F2:
    def a(self):
        print('F2.a')
class S(F2,F1):   ####从左到右执行
    pass
obj = S()
obj.a()
[root@python3 day1]# python3 class_test5.py
F2.a

 

F1上还继承F0

[root@python3 day1]# cat class_test5.py
#!/usr/local/python3/bin/python3
class F0:
    def a(self):
        print('F0.a')
class F1(F0):
    def a(self):
        print('F1.a')
class F2:
    def a(self):
        print('F2.a')
class S(F1,F2):      ##t先把F1
    pass
obj = S()
obj.a()
[root@python3 day1]# python3 class_test5.py
F1.a

[root@python3 day1]# cat class_test5.py
#!/usr/local/python3/bin/python3
class F0:
    def a(self):
        print('F0.a')
class F1(F0):
    def a1(self):           ###F1上没有,找F0
        print('F1.a')
class F2:
    def a(self):
        print('F2.a')
class S(F1,F2):
    pass
obj = S()
obj.a()
[root@python3 day1]# python3 class_test5.py
F0.a

[root@python3 day1]# cat class_test5.py
#!/usr/local/python3/bin/python3
class F0:
    def a1(self):            ##
        print('F0.a')
class F1(F0):
    def a1(self):            ##F1,F0都没有,再找F2
        print('F1.a')
class F2:
    def a(self):
        print('F2.a')
class S(F1,F2):
    pass
obj = S()
obj.a()
[root@python3 day1]# python3 class_test5.py
F2.a

 

多继承:存在共同根的情况

[root@python3 day1]# cat class_test5.py
#!/usr/local/python3/bin/python3
class Base:
    def a(self):
        print('Base.a')
class F0(Base):
    def a(self):
        print('F0.a')
class F1(F0):
    def a(self):
        print('F1.a')
class F2(Base):
    def a(self):
        print('F2.a')
class S(F1,F2):
    pass
obj = S()
obj.a()

 

方法中调用方法的情况

[root@python3 day1]# cat class_test6.py 
#!/usr/local/python3/bin/python3
class BaseRequest():
    pass

class RequestHandler(BaseRequest):
    def serve_forever(self):
        print('RequestHandler.serve_forever')

    def process_request(self):
        print('RequestHandler.process_request')

class Minx:
    def process_request(self):
        print('minx.process_request')

class Son(Minx, RequestHandler):
    pass

obj = Son()
obj.process_request()   #从左到右找,先找到Minx
[root@python3 day1]# python3 class_test6.py
minx.process_request

[root@python3 day1]# cat class_test6.py
#!/usr/local/python3/bin/python3
class BaseRequest():
    pass

class RequestHandler(BaseRequest):
    def serve_forever(self):  #self是对象obj,在外面可以执行obj.process_request(),所以在里面也可以执行
        print('RequestHandler.serve_forever')
        self.process_request()  
        #函数可以调用函数,在类中的方法也可以调用,self是obj,是Son()的对象,找时应该先去class Son中找

    def process_request(self): 
        print('RequestHandler.process_request')

class Minx:
    def process_request(self):
        print('minx.process_request')

class Son(Minx, RequestHandler):
    pass

obj = Son()
obj.serve_forever()  #serve_forever是对象调用的,
[root@python3 day1]# python3 class_test6.py
RequestHandler.serve_forever
minx.process_request

  

5.代码执行流程:加入init方法

[root@python3 day1]# cat class_test7.py
#!/usr/local/python3/bin/python3
class BaseRequest:
    def __init__(self):   
        print('BaseRequest.init')

class RequestHandler(BaseRequest):
    def __init__(self):  #默认情况下,一执行obj = Son(),这行代码init就执行,左边没有,右边第一个就找到了
        print('RequestHandler.init')
        BaseRequest.__init__(self)  #默认找到第一个init,就不会执行,所以要再加一个

    def serve_forever(self):
        print('RequestHandler.serve_forever')
        self.process_request()

    def process_request(self):
        print('RequestHandler.process_request')

class Minx:
    def process_request(self):
        print('minx.process_request')

class Son(Minx, RequestHandler):
    pass

obj = Son()   #init
obj.serve_forever()
[root@python3 day1]# python3 class_test7.py
RequestHandler.init        #默认找到第一个init就不会往下找
BaseRequest.init
RequestHandler.serve_forever
minx.process_request

  

6.面向对象之多态
描述:python中,多态可以忽略,如在java,要创建一个变量时,必须要指定这个变量是什么类型,是强类型的,如一个字符串,string v = 'reid',在Python中,v = 'reid',多态的引用是为了变量的值可以有多种形态
java

def func(string arg):
    print(arg)  #出现的形态只能是字符串
func('reid')
func(123)   #会报错,因为已经固定了类型

java中通过继承实现多态

class Foo:
    pass
class Son(Foo):
    pass
#声明func函数,函数接受Foo类或Foo子类的对象
def func(Foo arg):  #通过Foo来传入各种类型
    print(arg)
#obj = Foo()
obj = Son()
func(obj)

python原生多态

def func(arg):
    print(arg)  #形态不固定,字符串,数字...都行,这里体现了,python原生就是多态的
func(1)
func('reid')

  

7.Summary
a. 如何创建类

   class 类名:
        pass

b. 创建方法

    构造方法: __init__(self,arg)
              obj = 类('al')
    普通方法:
         obj = 类('xxx')
         obj.普通方法(

c. 面向对象三大特性之一: 封装(在对象里封装值)

        class Bar:
            def __init__(self,n,a):
                self.name = n
                self.age = a
                self.xue = 'o'
        b1 = Bar('reid',123)
        b2 = Bar('lin',567)

d. 适用场景
(1). 如果多个函数中有一些相同参数时,转换成面向对象,连接数据库的操作,这种情况使用面向对象比较好,因为做操作时,已经把一些值封装到对象中,只封装一次,使用时直接取就可以

class DataBaseHelper:
    def __init__(self,ip,port,username,pwd):
        self.ip = ip
        self.port = port
        self.username = username
        self.pwd = pwd
    def delete(self,content):
        #利用self中封装的用户,密码等去链接db
        print(content)
        #关闭数据库
    def update(self,content):       #每个操作都做相应的事
        #利用self中封装的用户,密码等去链接db
        print(content)
        #关闭数据库
    def get(self,content):
        #利用self中封装的用户,密码等去链接db
        print(content)
        #关闭数据库
s1 = DataBaseHelper('192.168.202.12',3306,'reid','123')

e.面向对象三大特性之二:继承

(1). 继承
    class 父类:
        pass
    class 子类(父类):
        pass
(2). 重写
    防止执行父类中的方法
(3). self 永远是执行方法的调用者
(4). 调用父类
    super(子类,self).父类中的方法(...)
    父类名.父类中的方法(self,...)
(4). python中支持多态

  

6.游戏实例
分析:人物创建三个对象,也就是三个人,每个人都有各种各样的打斗场景,写在类的方法

1. 创建三个游戏人物,分别是
- tom, male, 19, power1000
- jerry,male,20,power1800
- lin,female,18, power2500
2.游戏场景,分别:
- 草丛战斗, 消耗200power
- 自我修炼,增长100power
- 多人游戏,消耗500power

##########功能##########
class Person:  #根据类创建对象,这些值保存在自身的对象中
    def __init__(self,na,gen,age,fig):  
        self.name = na
        self.gender = gen
        self.age = age
        self.fight = fig
    def grassland(self):              #定义在各种模式下,战斗的值是对自身内部对象的值进行增加或者减少
        '''注释:草丛战斗, 消耗200power'''
        self.fight = self.fight - 200
    def practice(self):
        '''注释:自我修炼,增长100power'''        
        self.fight = self.fight + 200
    def multigame(self):
        '''注释:多人游戏,消耗500power'''        
        self.fight = self.fight - 500
    def detail(self):
        '''注释:当前对象详细情况'''
        temp = "name: %s; gender: %s; age: %s; power: %s" %(self.name, self.gender, self.age, self.fight)
        print temp

########开始游戏##########
cang = Person('tom','male',19, 1000)  #创建tom角色
dong = Person('jerry','male',20,1800)
bo = Person('lin','female',18. 2500)

cang.multigame()   #tom加入一次多人游戏
dong.practice()    # jerry自我修改一次
bo.grassland()     #lin参加一次草丛战斗

######输出当前所有人的详细情况#######
cang.detail()
dong.detail()
bo.detail()

 

posted @ 2018-04-24 09:30  Reid21  阅读(566)  评论(0编辑  收藏  举报