上一篇提到过类的属性,但没有详细介绍,本篇详细介绍一下类的属性
一 、类的属性
方法是用来操作数据的,而属性则是建模必不的内容,而且操作的数据,大多数是属性,比如游戏中的某个boss类,它的生命值就是属性(不同级别的boss,有不同的生命值),被攻击方法(不同的攻击,伤害值不同),当boss被攻击时,通过被攻击方法来减少boss自身的生命值,从而改变boss类的生命值属性。
python中类的属性有两类:实例属性和类属性 面向对象编程最大好处就是通过继承来减少代码,同时可以定制新类。类的继承,创建的新类称为了类,被继承的类为父类。子类继承父类后,子类就具有父类的属性和方法,但不能继承父类的私有属性和私有方法(属性名或方法名以两个下画线开头的),子类可以通过重载来修改父类的方法,以实现与父类不同的行为表现或能力。
下面通过一个代码实例,进行介绍,代码如下:
class Demo_Property: #定义类 class_name = "Demo_Property" #类属性 def __init__ (self,x=0): #实例属性 self.x = x def class_info(self): #输出信息方法 print("类变量值:",Demo_Property.class_name) print("实例变量值:",self.x) def chng(self,x): #修改实例属性的方法 self.x=x #注意实例属性的引用方式 def chng_cn(self,name): #修改类属性的方法 Demo_Property.class_name = name #注意类属性引用方式 dpa = Demo_Property() #创建一个对象dpa,也就是实例化类 dpb = Demo_Property() #创建一个对象dpb,即实例化类 print('初始化两个实例') dpa.class_info() dpb.class_info() print('修改实例变量') print('修改dpa 实例变量\n') dpa.chng(3) dpa.class_info() dpb.class_info() print('修改dpb实例变量\n') dpb.chng(10) dpa.class_info() dpb.class_info print('修改类变量') print('修改 dpa类变量\n') dpa.chng_cn ('dpa') dpa.class_info() dpb.class_info() print('修改dpb实例变量\n') dpb.chng_cn ('dpb') dpa.class_info() dpb.class_info()
代码说明:第一行定义Demo_property类,第二行class_name = "Demo_Property" #定义了类的属性class_name,接下来的两行,定义了实例属性x,
后面三个def 分别定义了一个输入信息的方法class_info,一个修改实例属性的方法chng,一个修改类属性的方法chng_cn。再创建了两个实例dpa和dpb。
dpa.class_info()和dpb.class_info()分别调用class_info()方法分别打印类变量值和实例变量值。后面的几行,分别通过修改变量,来实现实例变量、类变量的变化。运行结果如下:
二、类成员方法与静态方法
和属性一样,类的方法也有不同类型,主要有实例方法、类方法、静态方法。上述所有类中的方法都是实例方法,隐含调用参数是类的实例,类方法隐含调用的是类,静态方法没有隐含参数。
类方法和静态方法的定义方式与实例方法不同,调用方式也不相同。
静态方法定义的时候用装饰器@staticmethod进行修饰,没有默认参数
类方法定义时应用装饰器@classmethod进行修饰,必须有默认参数“cls”,两者调用方式可以直接由类名进行,既可用该类的任一个实例进行调用 ,也可以在
实例化前调用。如下例子:
class DemoMthd: @staticmethod #静态方法装饰器 def static_mthd(): #定义一个静态类 print("调用了静态方法!") @classmethod #类方法装饰器 def class_mthd(cls): #类方法定义,带默认参数cls print("调用了类方法!") DemoMthd.static_mthd() #未实例化类,通过类名调用静态方法 DemoMthd.class_mthd() #未实例化类,通过类名调用类方法 dm = DemoMthd () #创建对象,实例化 dm.static_mthd() #通过实例调用静态方法 dm.class_mthd() #通过实例调用类方法
注意:仔细分析上面代码中的注释。运行结果如下:
三、类的继承
通过上述例子,可以看出,我们在创建dpa和dpb时(其他例子中的多个对象),只通过实例化就创建了具体相同结构的对象,这就是面向对象编程的好处:减少代码量。
但如果dpa,dpb大部分结构相同,但又有所不同,比如游戏中的不同级别的boss,小boss,只有砍的攻击方法,而大boss,除了砍,还有喷火、扫腿……等不同的攻击方法(如上一篇中的,走、唱、跑方法一样),该如何处理?这就需要用到类的继承。类的继承,不仅可以减少代码量,同时还可以定制新类。
类的继承,创建的新类称为子类,被继承的类为父类。子类继承父类后,子类就具有父类的属性和方法,但不能继承父类的私有属性和私有方法(属性名或方法名以两个下画线开头的),子类可以通过重载(后面会演示)来修改父类的方法,以实现与父类不同的行为表现或能力。
那我们可以思考一下,将上一篇中的cat进行更加抽象成一个新类animal,然后cat的继承animal的属性,于是得到以下代码:
# -*- coding: utf-8 -*- """ Created on Sat Sep 16 19:59:24 2023 @author: Administrator """ def coord_chng(x,y): #定义一个全局函数,模拟坐标值变换 return (abs(x),abs(y)) #将x,y 值求绝对值后返回 class Animal: def __init__ (self,lifeva lue): self.lifeva lue=lifeva lue def info(self): #定义一个方法 print("当前位置:(%d,%d)"% (self.x,self.y)) def crawl(self,x,y): self.x=x self.y=y print("爬行……") self.info() def move(self,x,y): #定义一个方法move() x,y = coord_chng(x,y) #调用全局函数,坐标变换 self.edit_point(x,y) #