026--静态属性、类方法、静态方法、组合、继承
一、静态属性
class Room: tag=1 def __init__(self,name,owner,width,length,heigh): self.name=name self.owner=owner self.width=width self.length=length self.heigh=heigh @property def cal_area(self): # print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length)) return self.width * self.length
r1=Room('厕所','alex',100,100,100000)
print(r1.cal_area)
要点:@property + return 把公共函数变成数据属性,实例调用的调用的时候去掉小括号,像调用普通属性一样调用它。
二、类方法
class Room: tag=1 def __init__(self,name,owner,width,length,heigh): self.name=name self.owner=owner self.width=width self.length=length self.heigh=heigh @classmethod def tell_info(cls,x): print(cls) print('-->',cls.tag,x) r1=Room('厕所','alex',100,100,100000) Room.tell_info(10) #输出: <class '__main__.Room'> --> 1 10
要点:@classmethod 和 cls 专门供类使用的方法,类调用的时候不用传实例,也可以被实例调用(不建议这么做,本来就是划给类的方法,你还去调用它,四不是四傻)
三、静态方法
是一种普通函数,位于类定义的命名空间中,不会对任何实例类型进行操作,python为我们内置了函数staticmethod来把类中的函数定义成静态方法。
应用场景:编写类时需要采用很多不同的方式来创建实例,而我们只有一个__init__函数,此时静态方法就派上用场了。
class Room: tag=1 def __init__(self,name,owner,width,length,heigh): self.name=name self.owner=owner self.width=width self.length=length self.heigh=heigh @staticmethod def wash_body(a,b,c): print('%s %s %s正在洗澡' %(a,b,c)) Room.wash_body('alex','yuanhao','wupeiqi') print(Room.__dict__) r1=Room('厕所','alex',100,100,100000) print(r1.__dict__) r1.wash_body('alex','yuanhao','wupeiqi') #输出: alex yuanhao wupeiqi正在洗澡 { 'wash_body': <staticmethod object at 0x000000000261B438>, ..... } {'name': '厕所', 'owner': 'alex', 'width': 100, 'length': 100, 'heigh': 100000} alex yuanhao wupeiqi正在洗澡
class Date: def __init__(self,year,month,day): self.year=year self.month=month self.day=day @staticmethod def now(): #用Date.now()的形式去产生实例,该实例用的是当前时间 t=time.localtime() #获取结构化的时间格式 return Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回 @staticmethod def tomorrow():#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间 t=time.localtime(time.time()+86400) return Date(t.tm_year,t.tm_mon,t.tm_mday) a=Date('1987',11,27) #自己定义时间 b=Date.now() #采用当前时间 c=Date.tomorrow() #采用明天的时间 print(a.year,a.month,a.day) print(b.year,b.month,b.day) print(c.year,c.month,c.day)
要点:@staticmethod 只是名义上归属类管理,不能调用类变量、实例变量,只是类的工具包。
四、组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系。
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好。
class Trunk: pass class Head: pass class Person: def __init__(self,id_num,name): self.id_num=id_num self.name=name self.trunk=Trunk() self.head=Head() p1=Person('111111','alex') print(p1.name) print(p1.id_num) print(p1.__dict__) #输出: alex 111111 {'id_num': '111111', 'name': 'alex', 'trunk': <__main__.Trunk object at 0x000000000290B358>, 'head': <__main__.Head object at 0x000000000290B390>}
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 北京') c2=Course('linux',10,'1h',s1)
要点:把s1当做参数传进去,可以不写死。
五、继承
继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类。
class Grandfather: pass class Father(Grandfather): #单继承 Father是派生类,grandfather 是基类 pass class son(Father,Grandfather): #多继承 pass
继承使用产生的场景:如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时我们不可能从头开始写一个类B,这就用到了类的继承的概念。通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用。
除了继承与派生的概念还有一个概念是需要提出的那就是:组合。组合就是指在一个类中以另外一个类的对象作为数据属性,成为类的组合。
组合与继承两者到底什么的关系?1.继承的方式:通过继承建立了派生类与基类的关系,两者之间是“是”的关系。当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师 2.组合的方式:用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程(当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好)
class Vehicle1: 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('开动啦') print('开动啦') class Subway(Vehicle1): def __init__(self,name,speed,load,power,line): # Vehicle.__init__(self,name,speed,load,power) super().__init__(name,speed,load,power) #super(__class__,self).__init__(name,speed,load,power) self.line=line def show_info(self): print(self.name,self.speed,self.load,self.power,self.line) def run(self): # Vehicle.run(self) super().run() print('%s %s 线,开动啦' %(self.name,self.line)) line13=Subway('北京地铁','10km/s',1000000000,'电',13) line13.show_info() line13.run() print(line13.__class__)在子类中调用父类的例子
当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表)。
学习资料来源:海峰老师
- java继承 父类子类方法调用问题 属性和静态方法是没有多态的
- C++学习笔记4--静态属性 静态方法 虚方法 抽象方法 多态性 析构函数 运算符重载 多继承 虚继承
- java中静态属性和和静态方法的继承问题 以及多态的实质
- java中静态属性和和静态方法的继承问题以及多态的实质
- 如何实现在已有代码之后添加逻辑之继承,组合(静态代理)实现方法
- Java静态属性和方法的继承问题
- Java静态属性、静态方法、非静态属性、非静态方法的继承问题简单了解
- Java静态属性与静态方法能否被继承的问题
- 转载:JavasSript声明类、方法、属性、扩展方法、静态方法、继承
- 笔记整理 静态与非静态 继承哪一些 继承链 重写 属性方法重载 PDO
- java中静态属性和和静态方法的继承问题 以及多态的实质
- 关于java中静态属性、静态方法的继承问题
- javascript面向对象编程实现[定义(静态)属性方法--继承]
- javascript封装类的技巧:具有私有成员、私有方法、特权属性、特权方法、原型对象、静态成员,最重要的是不会失去封装的优点,并且不影响继承
- php函数、类和对象以及类的封装、继承、类的静态方法、静态属性
- JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
- Java静态属性和方法的继承问题
- 面向对象银角大王补充2-self就是调用当前方法的对象-静态字段,公有属性-封装的理解-继承的理解,普通方法,静态方法
- 面向对象---基于组合的继承:属性的继承基于伪装的方式实现,而方法的继承基于原型链的方式继承。
- java中静态属性和和静态方法的继承问题 以及多态的实质