翼度科技»论坛 编程开发 python 查看内容

python入门基础(14)--类的属性、成员方法、静态方法以及继承、重载

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
上一篇提到过类的属性,但没有详细介绍,本篇详细介绍一下类的属性
一 、类的属性
  方法是用来操作数据的,而属性则是建模必不的内容,而且操作的数据,大多数是属性,比如游戏中的某个boss类,它的生命值就是属性(不同级别的boss,有不同的生命值),被攻击方法(不同的攻击,伤害值不同),当boss被攻击时,通过被攻击方法来减少boss自身的生命值,从而改变boss类的生命值属性。  
   python中类的属性有两类:实例属性和类属性 面向对象编程最大好处就是通过继承来减少代码,同时可以定制新类。类的继承,创建的新类称为了类,被继承的类为父类。子类继承父类后,子类就具有父类的属性和方法,但不能继承父类的私有属性和私有方法(属性名或方法名以两个下画线开头的),子类可以通过重载来修改父类的方法,以实现与父类不同的行为表现或能力。
下面通过一个代码实例,进行介绍,代码如下:
  1. class Demo_Property:              #定义类
  2.     class_name = "Demo_Property"  #类属性
  3.     def __init__ (self,x=0):  #实例属性
  4.         self.x = x
  5.     def class_info(self):   #输出信息方法
  6.         print("类变量值:",Demo_Property.class_name)
  7.         print("实例变量值:",self.x)
  8.    
  9.     def chng(self,x):    #修改实例属性的方法
  10.         self.x=x  #注意实例属性的引用方式        
  11.         
  12.     def chng_cn(self,name):   #修改类属性的方法
  13.         Demo_Property.class_name = name  #注意类属性引用方式
  14.         
  15. dpa = Demo_Property()   #创建一个对象dpa,也就是实例化类
  16. dpb = Demo_Property()   #创建一个对象dpb,即实例化类
  17. print('初始化两个实例')
  18. dpa.class_info()
  19. dpb.class_info()
  20. print('修改实例变量')
  21. print('修改dpa 实例变量\n')
  22. dpa.chng(3)
  23. dpa.class_info()
  24. dpb.class_info()
  25. print('修改dpb实例变量\n')
  26. dpb.chng(10)
  27. dpa.class_info()
  28. dpb.class_info
  29. print('修改类变量')
  30. print('修改 dpa类变量\n')
  31. dpa.chng_cn ('dpa')
  32. dpa.class_info()
  33. dpb.class_info()
  34. print('修改dpb实例变量\n')
  35. dpb.chng_cn ('dpb')
  36. dpa.class_info()
  37. 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”,两者调用方式可以直接由类名进行,既可用该类的任一个实例进行调用 ,也可以在
实例化前调用。如下例子:
  1. class DemoMthd:
  2.     @staticmethod   #静态方法装饰器
  3.     def static_mthd():   #定义一个静态类
  4.         print("调用了静态方法!")
  5.     @classmethod    #类方法装饰器
  6.     def class_mthd(cls):  #类方法定义,带默认参数cls
  7.         print("调用了类方法!")
  8.         
  9. DemoMthd.static_mthd()   #未实例化类,通过类名调用静态方法
  10. DemoMthd.class_mthd()    #未实例化类,通过类名调用类方法
  11. dm = DemoMthd ()   #创建对象,实例化
  12. dm.static_mthd()   #通过实例调用静态方法
  13. dm.class_mthd()    #通过实例调用类方法
复制代码
注意:仔细分析上面代码中的注释。运行结果如下:

三、类的继承
       通过上述例子,可以看出,我们在创建dpa和dpb时(其他例子中的多个对象),只通过实例化就创建了具体相同结构的对象,这就是面向对象编程的好处:减少代码量。
但如果dpa,dpb大部分结构相同,但又有所不同,比如游戏中的不同级别的boss,小boss,只有砍的攻击方法,而大boss,除了砍,还有喷火、扫腿……等不同的攻击方法(如上一篇中的,走、唱、跑方法一样),该如何处理?这就需要用到类的继承。类的继承,不仅可以减少代码量,同时还可以定制新类。
类的继承,创建的新类称为子类,被继承的类为父类。子类继承父类后,子类就具有父类的属性和方法,但不能继承父类的私有属性和私有方法(属性名或方法名以两个下画线开头的),子类可以通过重载(后面会演示)来修改父类的方法,以实现与父类不同的行为表现或能力。
那我们可以思考一下,将上一篇中的cat进行更加抽象成一个新类animal,然后cat的继承animal的属性,于是得到以下代码:
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sat Sep 16 19:59:24 2023
  4. @author: Administrator
  5. """
  6. def coord_chng(x,y):        #定义一个全局函数,模拟坐标值变换
  7.     return (abs(x),abs(y))  #将x,y 值求绝对值后返回
  8. class Animal:
  9.     def __init__ (self,lifevalue):
  10.         self.lifevalue=lifevalue
  11.         
  12.     def info(self):      #定义一个方法
  13.          print("当前位置:(%d,%d)"% (self.x,self.y))   
  14.     def crawl(self,x,y):
  15.          self.x=x
  16.          self.y=y
  17.          print("爬行……")
  18.          self.info()   
  19.          
  20.     def move(self,x,y):        #定义一个方法move()
  21.             x,y = coord_chng(x,y)  #调用全局函数,坐标变换
  22.             self.edit_point(x,y)   #调用类中的方法edit_point()
  23.             self.disp_point()      #调用类中的方法disp_point()
  24.         
  25.     def edit_point(self,x,y):  #定义一个方法
  26.             self.x += x
  27.             self.y += y
  28.     def disp_point(self):      #定义一个方法
  29.             print("当前位置:(%d,%d)"% (self.x,self.y))     
  30.    
  31. class Cat(Animal):          #定义一个类Cat类,继承类Animal
  32.     def __init__ (self,x=0,y=0,color="white"):  #定义一个构造方法
  33.         self.x=x
  34.         self.y=y
  35.         self.color=color      #新增加一个颜色
  36.         self.disp_point()      #构造函数中调用类中的方法disp_point()
  37.    
  38.     def run(self,x,y):        #定义一个方法run()
  39.             x,y = coord_chng(x,y)  #调用全局函数,坐标变换
  40.             self.edit_point(x,y)   #调用类中的方法edit_point()
  41.             self.disp_point()      #调用类中的方法disp_point()
  42.      
  43. cat_a= Cat()      #实例化Cat()类
  44. cat_a.move(2,4)   #调用cat_a实例的方法move()
  45. cat_a.move(-9,6)  #调用cat_a实例的方法move()
  46. cat_a.move(12,-16)#调用cat_a实例的方法move()
  47. cat_a.run(12,-16) #调用cat_a实例的方法run()
复制代码
注意红色注释部分,move()这个方法是Cat类没有的,但在Animal中有,Cat类通过继承Animal类,获得了Animal中move方法。
同样,也可以将上篇中的Person类继承Animal类的功能,并进行少量修改,全部代码如下:
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sun Sep 17 19:59:24 2023
  4. @author: Administrator
  5. """
  6. def coord_chng(x,y):        #定义一个全局函数,模拟坐标值变换
  7.     return (abs(x),abs(y))  #将x,y 值求绝对值后返回
  8. class Animal:
  9.     def __init__ (self,lifevalue):
  10.         self.lifevalue=lifevalue
  11.         
  12.     def info(self):      #定义一个方法
  13.          print("当前位置:(%d,%d)"% (self.x,self.y))   
  14.     def crawl(self,x,y):
  15.          self.x=x
  16.          self.y=y
  17.          print("爬行……")
  18.          self.info()  <br>         
  19.     def move(self,x,y):        #定义一个方法move()
  20.             x,y = coord_chng(x,y)  #调用全局函数,坐标变换
  21.             self.edit_point(x,y)   #调用类中的方法edit_point()
  22.             self.disp_point()      #调用类中的方法disp_point()
  23.         
  24.     def edit_point(self,x,y):  #定义一个方法
  25.             self.x += x
  26.             self.y += y
  27.     def disp_point(self):      #定义一个方法
  28.             print("当前位置:(%d,%d)"% (self.x,self.y))     
  29.    
  30. class Cat(Animal):          #定义一个类Cat类,继承类Animal
  31.     def __init__ (self,x=0,y=0,color="white"):  #定义一个构造方法
  32.         self.x=x
  33.         self.y=y
  34.         self.color=color      #新增加一个颜色
  35.         self.disp_point()      #构造函数中调用类中的方法disp_point()
  36.    
  37.      
  38. class Person(Animal):          #定义一个类Person类,继承类Animal
  39.     def __init__(self,new_name,x,y,new_age,new_hight,new_weight,edu_certification,new_job):
  40.         #self.name = "Tom"
  41.         self.x=x
  42.         self.y=y
  43.         self.name=new_name
  44.         self.age=new_age
  45.         self.hight=new_hight
  46.         self.weight=new_weight
  47.         self.edu_certif=edu_certification
  48.         self.job=new_job
  49.     def eat(self):
  50.            # 哪一个对象调用的方法,self就是哪一个对象的引用
  51.            print("%s 爱吃鱼" % self.name)
  52.     def drink(self):
  53.            print("%s 要喝水" % self.name)
  54.            
  55.     def walk(self):
  56.         print("%s今天步行了10公里"%self.name)
  57.         
  58.     def run(self):        # 必须返回一个字符串
  59.         return "%s跑了10公里,用时56分钟。" % self.name   
  60.     def sing(self):        # 必须返回一个字符串
  61.         return "%s唱了一首《我的中国心》" % self.name   
  62.     def working(self):        # 必须返回一个字符串
  63.         return "%s工作了很久!" % self.name  
  64. tom=Person("Tom",10,20,24,175,70,"bachelor","writer")
  65. #lucy=Person("Lucy")
  66. #lily=Person("Lily")
  67. print("%s的身高是%s cm\n" %(tom.name,tom.hight))
  68. print("%s的体重是%sKG\n" %(tom.name,tom.weight))
  69. print(tom.sing())
  70. print(tom.run())
  71. tom.move(2,4)
  72. tom.move(10,-12)
  73. print("------------------显示分隔线--------------------\n")
  74. cat_a= Cat()      #实例化Cat()类
  75. cat_a.move(2,4)   #调用cat_a实例的方法move()
  76. cat_a.move(12,-16)#调用cat_a实例的方法move()
复制代码
代码中红色部分为修改。可以看出,tom继承Animal类后,也继承了move()方法。运行结果:
 

四、类的多重继承
python编程中,一个类不仅可以继承一个类,还可以继承多个类,即多重继承。和上述所讲继承一样,只不过在括号中,用“,”分隔开。可以当作思考题,自动动手,比如利用上述的person类,Cat类,创建一个怪物类,然后实例化。
五、方法的重载
当子类继承父类时,子类如果要想修改父类的行为,则应使用方法重载来实现,
方法重载:在子类中定义一个和所继承的父类中,同名的方法。
比如,上述代码中animal类中有一个move()方法,如果将子类Person中的def run(self) 修改为def move(self),即move()方法被 重载了
当用子类Person创建对象(实例化)后,调用的是Person类中的move()。
同样,如果在多重继承中,两个父类具有同名方法,为避免不要求的错误,在子类中对该方法进行重载。
 
 
翻译
搜索
复制

来源:https://www.cnblogs.com/codingchen/p/17708314.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具