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()