python基础11-静态属性/类方法/静态方法/组合/面向对象三大特性之继承
- 面向对象的类中,函数属性跟实际生活的行为还是有区别的,可以将学校的基本信息定义为函数
-
静态属性,实际就是数据属性
-
class Room: def _init_(self,name,owner,width,length) self.name= name self.name=owner self. @property#将函数属性封装成静态属性,不用()即可运行 def cal_area(self): return(self.width * self.length) print(r1.cal_area) print(r2.cal_area)
-
类方法
- 不跟实例捆绑,直接调用自己的方法。跟实例完全区分开
-
@classmethod
def tell_info(cls):#这是类方法,类名.类方法,自动传参数。不能访问实例属性
print(cls)
print('-->',cls.tag)
#def tell_info(self): #print('--->',self.tag) -
静态方法
- 只是名义上归属类管理,不能使用类变量和实例变量,是类的工具包
-
@staticmethod#类的工具包,跟实例和类都不绑定 def wash_body(a,b,c): print('%s%s%s正在洗澡'%(a,b,c)) Room.wash_body('alex','yuanhao','wupeiqi') def test(x,y):#这种定义,实例不能调用,实例是传self print(x,y)
-
组合
- 类之间的组合使用,就叫组合
-
#定义组合类 class School: def __init__(self, name, addr): self.name = name self.addr = addr def zhao_sheng(self): print('%s正在招生' % self.name) class Course: def __init__(self, name, price, period, school): self.name = name self.price = price self.period = period self.school = school s1 = School('oldboy北京校区', '北京') s2 = School('oldboy南京校区', '南京') s3 = School('oldboy东京校区', '东京') # # c1=Course('linux',10,'1h','oldboy 北京') # c1 = Course('linux', 10, '1h', s1) # # print(c1.__dict__) # print(c1.school.name) # print(s1.name) msg = ''' 1 老男孩北京校区 2 老男孩南京校区 3 老男孩东京校区 ''' while True: print(msg) menu = { '1': s1, '2': s2, '3': s3, } choice = input('选择学校>>:') school_obj = menu[choice] name = input('课程名字>>:') price = input('课程费用>>:') period = input('课程周期>>:') new_course = Course(name, price, period, school_obj) print('课程[%s]属于[%s]学校' % \ (new_course.name, new_course.school.name))
-
面向对象编程三大特性:继承,多态,封装
- 继承,派生衍生出新动作
-
class ParentClass1: pass class ParentClass2: pass class Subclass(ParentClass1): # 单继承 pass class Subclass(ParentClass1, ParentClass2): # 多继承 pass
- 子类可以调用父类的数据属性和函数属性
- 子类优先调用自己的属性,然后去找父类的,即使重名也是如此,并没有覆盖父类属性
- 当类之间显著不同,小类是大类的组件时,用组合。当类之间有很多相同功能,提取这些共同功能作为基类,用继承,基类即父类
- 接口继承,父类定义基本方法,但是父类不实现,子类必须能具体的实现父类的方法。
-
#归一化设计,使得高层,相对于底层开发而言的高层,外部使用者可以不加区分的处理所有接口兼容的对象集合 import abc#子类必须实现读和写的方法 class All_file(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass
- python可以继承多个类,java和c#只能继承一个类
- 新式类继承类时,应用广度优先,先左支走到头,不包括基类,然后走右边,最后找基类。F.__mro__中存储有子类继承多个父类的继承顺序
- 新式类的子类也是新式类。在python2中,只要基类没有继承object,就是经典类。python2的经典类,是深度遍历,中途会检测基类
-
子类调用父类的方法
-
class Vehicle: Country='China' def __init__(self,name,speed,load,power): self.name=name self.speed=speed self.load=load self.power=power def run(self): print('开动啦') class Subway(Vehicle): def __init__(self,name,speed,load,power,line): #子类调用父类的方法,函数属性 # Vehicle.__init__(self,name,speed,load,power)#得写self,类调用自己的函数属性时,要传。子类调用不用传 super().__init__(name,speed,load,power)#通过super方法调用父类方法 self.line=line def show_info(self): print(self.name,self.line) def run(self): # Vehicle.run(self)#子类中调用父类的函数属性 super().run() print('%s%s号线才开动啦'%(self.name,self.line)) line13=Subway('北京地铁','10km/s','100000','电',13) line13.show_info() line13.run()
-
应用举例
-
import pickle class Base: def save(self): with open('school.db', 'wb') as f: pickle.dump(self, f) # 通过此种方式,将学校信息写入f中 class School(Base): def __init__(self, name, addr): self.name = name self.addr = addr class Course(Base): def __init__(self, name, price, period, school): self.name = name self.price = price self.period = period self.school = school school_obj = pickle.load(open('school.db', 'rb'))#打开存储有学校信息的文件 print(school_obj.name, school_obj.addr) # s1=School('oldboy','北京') # s1.save()#存储上述学校的信息