一 类的命名空间
1 对于类的静态属性:如果类.属性:调用的解释累的属性
对象.属性:就是先从自己的命名空间寻找,如果有就用自己的,没有就到类里面去寻找,如果有就用类里面的,没有就会报错。
实例:
# class A: # ret='fang' # a=A() # print(A.ret) # print(a.ret) # a.ret='famgjie' # print(a.ret) # print(A.ret)
2 关于类的动态属性(方法):这个方法本身就存在于类的空间,根本不会存在对象的内存中。
如果在对象调用类里面的方法,需要在类的内存中产生一个地址簿来对应类中的方法。
# class A: # def func(self): # print(111) # a=A() # a.func() # a.func=666 # print(a.func) # a.func() #这个就报错了
3 关于对象的属性:对象的属性只存在于对象的命名空间,
只能被对象来调用和修改,如果类来调用或修改就会报错。
# class A: # pass # a=A() # a.name='alex' # print(a.name) # print(A.name) #这个就会报错
二 面向对象的组合
1 什么叫组合:一个类的对象是另一个类的属性就叫做组合,组合表达的是什么和什么的关系。
2 组合的好处:增强了代码的重用性。
实例1 :计算圆环的面积差和圆环面积总周长
import math class Yuan: def __init__(self,ban): self.ban=ban def mian(self): return math.pi*self.ban**2 def zhou(self): return math.pi*self.ban*2 class DaXiaoYuan: def __init__(self,daban,xiaoban): self.dayuan=Yuan(daban) self.xiaoyuan=Yuan(xiaoban) def mian(self): return self.dayuan.mian() - self.xiaoyuan.mian() def zhou(self): return self.dayuan.zhou() + self.xiaoyuan.zhou() yuan=DaXiaoYuan(20,10) print(yuan.mian()) print(yuan.zhou())
实例2:课程和学生关联
# class Course: # def __init__(self,course_name,period,price,teacher): # self.course_name=course_name # self.period=period # self.price=price # self.teacher=teacher # class People: # def __init__(self,name,age,sex,course): # self.name=name # self.age=age # self.sex=sex # self.course=course # py=Course('python',8,20000,'景姐姐') # stdent_1=People('fang',18,'男',py) # print(stdent_1.course.period)
实例3:人狗大战
# class People: # def __init__(self,name,sex,aggr,blood): # self.name=name # self.sex=sex # self.aggr=aggr # self.blood=blood # def dajia(self,dog): # print('%s打了%s一拳'%(self.name,dog.name)) # dog.blood-=self.aggr # print(dog.blood) # class Dog: # def __init__(self,name,aggr,blood): # self.name=name # self.aggr=aggr # self.blood=blood # def yao(self,person): # print('%s咬了%s一口'%(self.name,person.name)) # person.blood-=self.aggr # print(person.blood) # class Wuqi: # def __init__(self,wuqi_name,aggr,xi_blood): # self.wuqi_name=wuqi_name # self.aggr=aggr # self.xi_blood=xi_blood # def gongji(self,dog,person): # dog.blood-=self.aggr # person.blood+=self.xi_blood # egon=People('egon','nan',2000,100000) # alex=Dog('alex',1,4000) # fthj=Wuqi('fangtianhuaji',2000,2000) # alex.yao(egon) # egon.wuqi=fthj.gongji(alex,egon) # egon.dajia(alex) # print('KO')
三 组合与重用性
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
组合:什么有什么的关系,也是为了减少重复代码
其实早在3.5小节中我们就体会了组合的用法,比如一个英雄有一个装备
1 >>> class Equip: #武器装备类 2 ... def fire(self): 3 ... print('release Fire skill') 4 ... 5 >>> class Riven: #英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类 6 ... camp='Noxus' 7 ... def __init__(self,nickname): 8 ... self.nickname=nickname 9 ... self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性 10 ... 11 >>> r1=Riven('锐雯雯') 12 >>> r1.equip.fire() #可以使用组合的类产生的对象所持有的方法 13 release Fire skill
组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,
1.继承的方式
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师
1 >>> class Teacher: 2 ... def __init__(self,name,gender): 3 ... self.name=name 4 ... self.gender=gender 5 ... def teach(self): 6 ... print('teaching') 7 ... 8 >>> 9 >>> class Professor(Teacher): 10 ... pass 11 ... 12 >>> p1=Professor('egon','male') 13 >>> p1.teach() 14 teaching
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程
1 class People: 2 # def __init__(self,name,age,year,mon,day): 3 # self.name=name 4 # self.age=age 5 # self.birth=Date(year,mon,day) 6 # def walk(self): 7 # print('%s is walking' %self.name) 8 # class Date: 9 # def __init__(self,year,mon,day): 10 # self.year=year 11 # self.mon=mon 12 # self.day=day 13 # def tell_birth(self): 14 # print("出生于<%s>年 <%s>月 <%s>日"%(self.year,self.mon,self.day)) 15 # 16 # class Student(People): 17 # def __init__(self,name,age,year,mon,day,group): 18 # People.__init__(self,name,age,year,mon,day) 19 # self.group=group 20 # def study(self): 21 # print('%s is studying' %self.name) 22 # 23 # class Teacher(People): 24 # def __init__(self,name,age,year,mon,day,level,salary): 25 # People.__init__(self,name,age,year,mon,day) 26 # self.level=level 27 # self.salsry=salary 28 # def teach(self): 29 # print('%s is teaching' %self.name) 30 # 31 # t=Teacher('egon',18,1990,2,33) 32 # print(t.name,t.age) 33 # print(t.birth) 34 # print(t.birth.year) 35 # print(t.birth.mon) 36 # print(t.birth.day) 37 # 38 # 39 # 40 # t=Student('fang',18,1990,2,25) 41 # print(t.name,t.age) 42 # print(t.birth) 43 # print(t.birth.year) 44 # print(t.birth.mon) 45 # print(t.birth.day)
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
3 关于对象的属性:对象的属性只存在于对象的命名空间, 只能被对象来调用和修改,如果类来调用或修改就会报错。