静态属性
在类中函数前加@property,在实例调用函数时无需加(),将函数属性封装,调用时看起来与数据属性类似
将函数封装成数据属性的形式,外部调用时看不到逻辑,静态属性可以访问实例属性也可以访问类属性
class House: def __init__(self,name,owner,width,length,height): self.name=name self.owner=owner self.width=width self.length=length self.height=height @property def cal_area(self): return self.width*self.length H1=House('御景','我',100,100,100) H2=House('峰景','她',50,50,50) print(H1.cal_area) print(H2.cal_area)
类方法:
与实例区分开,为了满足只调用类方法,与实例无关;在方法前加@classmethod
类方法只给类使用(不论是否存在实例),只能访问实例变量
class Room: tag=1
@classmethod def tell_info(cls): print(cls.tag) Room.tell_info()
静态方法:
与类和实例都不绑定的方法,在方法前加@staticmethod,称作类的工具包
静态方法名义上归属类管理,不能使用类变量和实例变量,是类的工具包
静态方法不能访问类属性,也不能访问实例属性
class Room: tag=1 @staticmethod def bath(a,b): print('%s%s在洗澡'%(a,b)) Room.bath('a','b')
组合
用来实现类与类之间的关联
class School: def __init__(self,name,addr): self.name=name self.addr=addr class Course: def __init__(self,name,price,school): self.name=name self.price=price self.school=school s1=School('oldboy','Beijing') c1=Course('linux','1000',s1) print(c1.school) print(c1.school.addr)
class School: def __init__(self,name,addr): self.name=name self.addr=addr class Course: def __init__(self,name,price,school): self.name=name self.price=price self.school=school s1=School('old','Beijing') s2=School('old2','Nanjing') s3=School('old3','Dongjing') c1=Course('linux','1000',s1) msg=''' 1 oldman 北京校区 2 oldman 南京校区 3 oldman 杭州校区 ''' menu={ '1':s1, '2':s2, '3':s3 } while True: print(msg) choice = input('请输入选择校区>>>') school_obj=menu[choice] name=input('请输入课程名>>>') course_obj=Course(name,1000,school_obj) print('%s课程是%s学校的'%(course_obj.name,course_obj.school.name))
继承:
类的继承与生活中的父、子、孙子继承关系一样,父类又称基类。
python中的继承分为单继承和多继承
子类实例调用方法时会优先调用自身类的方法,找不到再找继承基类中方法,子类中方法与父类方法名相同时,相当于重新声明,原则上不是覆盖,与函数的作用域类似。
class Parent1: pass class Parent2: pass class son1(Parent1): pass class son2(Parent1,Parent2): pass
1.当类之间有显著不同,且较小的类是较大的类的所需要的组件时,用组合比较好。
例:人的手类、脚类、头类
2.当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好。
例:男人可以:吃饭、睡觉、打豆豆
女人可以:吃饭、睡觉、打豆豆
继承的两种含义:
1.继承基类方法,并且做出自己的改变或者扩展(代码重用),该方式有一定缺点,会使子类与基类耦合。
2.声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口类中定义的方法,接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”-----这叫做归一化。通俗来讲,就是规定子类必须实现父类中抽象的方法,否则无法实例化。需导入abc模块
import abc class Parent(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass class son(Parent): def read(self): print('111') def write(self): print('222') s1=son()
继承顺序:
__mro__方法可查看继承顺序
子类中继承父类方法
方法一:
class Vehicle: def __init__(self,name,speed,load): self.name=name self.speed=speed self.load=load def run(self): print('run') class Subway(Vehicle): def __init__(self,name,speed,load,line): Vehicle.__init__(self,name,speed,load) self.line=line def run(self): Vehicle.run(self) print('%s line %s run '%(self.name,self.line),self.speed,self.load) S1=Subway('Wuhan','100km/h',1000,'7') S1.run()
方法二:
super().__init__()方法,可以无需写父类名,无需传self参数
class Vehicle: def __init__(self,name,speed,load): self.name=name self.speed=speed self.load=load def run(self): print('run') class Subway(Vehicle): def __init__(self,name,speed,load,line): super().__init__(name,speed,load) self.line=line def run(self): super().run() print('%s line %s run '%(self.name,self.line),self.speed,self.load) S1=Subway('Wuhan','100km/h',1000,'7') S1.run()
1