Python-27_面向对象
# 三大编程范式: # 1、面向过程编程 # 2、函数式编程 # 3、面向对象编程 # 特点: # 面向过程---复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现) # 面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式 # 面向对象---解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。 # 对象是具体的存在,而类仅仅只是一个概念,并不真实存在!! # 在程序中:务必保证先定义类,后产生对象!! # # 如果我们把数据和动作内嵌到一个结构(函数或类)中,那么我们就有了一个“对象系统”(对象就是数据与函数整合到一起的产物) # # # ##### 面向对象设计:将一类具体事物的数据和动作整合到一起,即为面向对象设计。 # ##### 面向对象编程:用定义类+实例/对象的方法去实现面向设计。 # # 类------把一类事物的相同特征和动作整合到一起就是类,类是一个抽象的概念; # 对象------基于类而创建的一个具体的事物(一个具体的存在),也是特征和动作整合到一起; # 实例化------由类生产对象的过程叫实例化; # 例子:----初接触 # def people(name,age,gender): # 这是一个类,统称为:人 # def eat(x): # print("%s正在吃饭饭,请不要打扰"%x["name"]) # def wushu(x): # print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(x["name"],x["name"],x["gender"],x["age"])) # def feature(name,age,gender): # 对对象进行初始化 # dic={"name":name,"age":age,"gender":gender,"eat":eat,"wushu":wushu} # return dic # return feature(name,age,gender) # people01=people("newmet1",15,"男") # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在 # print(people01) # people01["wushu"](people01) # people01["eat"](people01) # 例子:----面向对象编程: class people: # 这是一个类,统称为:人 def eat(self): print("%s正在吃饭饭,请不要打扰"%self.name) def wushu(self): print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age)) def __init__(self,name,age,gender): # 初始化函数 self.name=name self.age=age self.gender=gender people01=people("newmet1",15,"男") # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在 print(people01.__dict__) # {'name': 'newmet1', 'age': 15, 'gender': '男'} people01.eat() # newmet1正在吃饭饭,请不要打扰 people01.wushu() # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁 # 用面向对象语言写程序(是利用class等方法写),和一个程序的设计是面向对象的,完全是两回事!!
#-------------- 类 --------------# # class School: # # 这个类具体是干什么用的 # # pass # v=School() # 类的实例化(类名+()) # print(v) # <__main__.School object at 0x00000000020A6400> # 一、经典类、新式类 # python2 中,类分:经典类、新式类; # python3 中,类只有新式类(就是python2中的经典类) # 经典类: # class 类名: # pass # 新式类: # class 类名(父类): # 这个类继承自--父类 # pass # 二、类:属性: # 1、数据属性 # 2、函数属性 class friend: "这是一个朋友类" v=111 def s(): print("222") print(dir(friend)) # 查出的是一个名字列表 print(friend.__dict__) # 查看属性字典(内存地址) print(friend.v) # 111 friend.s() # 222 print(friend.__dict__["v"]) # 111 friend.__dict__["s"]() # 222 print(friend.__name__) # friend print(friend.__doc__) # 这是一个朋友类 print(friend.__base__) # <class 'object'> print(friend.__bases__) # (<class 'object'>,) print(friend.__module__) # __main__ print(friend.__class__) # <class 'type'> """ #python为类内置的特殊属性 类名.__name__ # 类的名字(字符串) 类名.__doc__ # 类的文档字符串 类名.__base__ # 类的第一个父类(在讲继承时会讲) 类名.__bases__ # 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__ # 类的属性字典 类名.__module__ # 类定义所在的模块 类名.__class__ # 实例对应的类(仅新式类中) """
class people: # 这是一个类,统称为:人 def eat(self): print("%s正在吃饭饭,请不要打扰"%self.name) def wushu(self): print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age)) def __init__(self,name,age,gender): # 初始化函数 self.name=name self.age=age self.gender=gender v1=people("newmet1",15,"男") # 实例化的过程 self --- v1 其就是实例化的结果 print(v1.__dict__) # {'name': 'newmet1', 'age': 15, 'gender': '男'} v1.eat() # 自动给eat传了一个self参数 # newmet1正在吃饭饭,请不要打扰 v1.wushu() # 自动给wushu传了一个self参数 # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁 print(v1.__dict__["name"]) # newmet1 print(v1.name) # newmet1
class friend: def __init__(self,name): print("名字:%s"%name) name="newmet" def play_ball(self): print("正在打球") # 增加 # friend.age=18 # # def eat(): # print("函数属性增加") # friend.eat=eat # print(friend.__dict__) # friend.eat() # 删除 # del friend.name # print(friend.__dict__) # 修改 friend.name="2222" def eat(): print("函数属性修改") friend.play_ball=eat print(friend.name) print(friend.play_ball())
class friend: def __init__(self,name): self.name=name age=18 def play_ball(self): print("正在打球") v=friend("newmet") print(v.__dict__) # 查看 # print(v.age) # print(v.play_ball) # 增加 (实例属性只能增加数据属性) v.gender="男" print(v.__dict__) print(v.gender) # 修改 v.name="121" print(v.__dict__) print(v.name)
country="中国-----------" class Chinese: country="中国" def __init__(self,name): self.name=name print(">>>",country) # 没.(没实例化) 不在类中找,与实例无关 def play_ball(self,ball): print("%s 正在玩 %s" %(self.name,ball)) print(Chinese.__dict__) print(Chinese.country) # 中国 p=Chinese("new") # >>> 中国----------- 没.(没实例化) 不在类中找,与实例无关 print("实例化",p.country) # 实例化 中国
#--------------------------------- 静态属性 --------------------------------# # class Room: # def __init__(self,name,owner,length,width,height): # self.name=name # self.owner=owner # self.length=length # self.width=width # self.heigth=height # @property # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。 # def cal_area(self): # # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width))) # return self.length*self.width # # v1=Room("1号房间","new1",50,50,4) # v2=Room("2号房间","new2",30,30,4) # # v1.cal_area() # new1住在叫1号房间的2500平米的房子中 # # v2.cal_area() # new2住在叫2号房间的900平米的房子中 # # v1.cal_area # new1住在叫1号房间的2500平米的房子中(类中增加 @property 后,不需要加括号) # # v2.cal_area # new2住在叫2号房间的900平米的房子中 (类中增加 @property 后,不需要加括号) # # print(v1.cal_area) # 2500 @property隐藏背后的逻辑,调用方式表面上和调用数据属性一样。 # print(v2.cal_area) # 900 # print(v1.name) # 1号房间 调用数据属性 # print(v2.name) # 2号房间 #--------------------------------- 类方法 --------------------------------# # class Room: # food=1 # def __init__(self,name,owner,length,width,height): # self.name=name # self.owner=owner # self.length=length # self.width=width # self.heigth=height # @classmethod # 将下列方法变成可以被类调用的方法 # def cal_area(cls): # print(cls) # <class '__main__.Room'> # print("%s newmet"%cls.food) # 1 newmet # # # v1=Room("1号房间","new1",50,50,4) # # v2=Room("2号房间","new2",30,30,4) # Room.cal_area() # # 类调用自己的属性方法的时候 ,与实例没有关系 #--------------------------------- 静态方法 --------------------------------# class Room: food=1 def __init__(self,name,owner,length,width,height): self.name=name self.owner=owner self.length=length self.width=width self.heigth=height @property # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。 def cal_area(self): # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width))) return self.length*self.width @classmethod # 将下列方法变成可以被类调用的方法 def cal_area1(cls): print(cls) # <class '__main__.Room'> print("%s newmet"%cls.food) # 1 newmet @staticmethod def bath(x): print("%s 正在沐浴" %x) Room.cal_area1() Room.bath("new") v1=Room("1号房间","new1",50,50,4) v1.bath("met") # @property ---- 和实例绑定,与类无关 # @classmethod ---- 和类绑定,与实例无关 # @staticmethod ---- 和类和实例均不绑定(类的工具包) # @staticmethod -- 静态方法只是名义上的归属类管理,不能使用类变量和实例变量,只是类的工具包 #--------------------------------- 总结 --------------------------------# # @property ---- 能访问类的数据、函数属性以及实例的属性 # @classmethod ---- 只能访问类的属性 # @staticmethod ---- 不能访问类、实例属性
#--------------------- 定义锐雯类:--------------------- class Raven: camp='Noxus' def __init__(self,nickname, aggressivity=54, life_value=414, money=1001, armor=3): self.nickname=nickname self.aggressivity=aggressivity self.life_value=life_value self.money=money self.armor=armor def attack(self,enemy): damage_value=self.aggressivity-enemy.armor enemy.life_value-=damage_value #--------------------- 定义盖伦类:--------------------- class Galen: camp='Demacia' def __init__(self,nickname, aggressivity=58, life_value=455, money=100, armor=10): self.nickname=nickname self.aggressivity=aggressivity self.life_value=life_value self.money=money self.armor=armor def attack(self,enemy): damage_value=self.aggressivity-enemy.armor enemy.life_value-=damage_value #--------------------- 定义装备:--------------------- class BlackCleaver: def __init__(self,price=475,aggrev=9,life_value=100): self.price=price self.aggrev=aggrev self.life_value=life_value def update(self,obj): obj.money-=self.price #减钱 obj.aggressivity+=self.aggrev #加攻击 obj.life_value+=self.life_value #加生命值 def fire(self,obj): #这是该装备的主动技能,喷火,烧死对方 obj.life_value-=1000 #假设火烧的攻击力是1000 #--------------------- 测试交互:--------------------- r1=Raven('草丛伦') g1=Galen('盖伦') b1=BlackCleaver() print(r1.aggressivity,r1.life_value,r1.money) #r1的攻击力,生命值,护甲 if r1.money > b1.price: r1.b1=b1 b1.update(r1) print(r1.aggressivity,r1.life_value,r1.money) #r1的攻击力,生命值,护甲 print(g1.life_value) r1.attack(g1) #普通攻击 print(g1.life_value) r1.b1.fire(g1) #用装备攻击 print(g1.life_value) #g1的生命值小于0就死了
# 获取指定位置上的·某个方向·指定数量的元素。 # 变化特征 "20" 右侧 0 1 (索引列r、行c、累加) # 变化特征 "31" 上方 -1 0 (索引列r、行c、累加) # 变化特征 "24" 左侧 0 -1 (索引列r、行c、累加) # 变化特征 "03" 下方 1 0 (索引列r、行c、累加) # # def get_elements(list_target,r_index,c_index,r_dir,c_dir,count): # """ # 获取指定位置上的·某个方向·指定数量的元素。 # :param list_target: list # :param r_index:列索引 # :param c_index:行索引 # :param r_dir:方向 # :param c_dir:方向 # :param count:次数--数量 # :return: # """ # result = [] # for item in range(count): # r_index += r_dir # c_index += c_dir # result.append(list_target[r_index][c_index]) # return result # # # list01=[ # ["00","01","02","03","04"], # ["10","11","12","13","14"], # ["20","21","22","23","24"], # ["30","31","32","33","34"], # ["40","41","42","43","44"] # ] # # # print(get_elements(list01,2,4,0,-1,3)) """ 该方式是:面向过程 缺点: 1.代码可读性差 2.每次调用方法,都需要思考方向(索引变化)的特征 """ # 解决方法: # 1.使用一个类,包装两个数据(行/列) # 2.利用静态方法 class Vector2: def __init__(self, x, y): self.x = x self.y = y # def right(self): # return Vector2(0,1) # 静态方法:不依赖于对象、类 @staticmethod def right(): return Vector2(0, 1) @staticmethod def up(): return Vector2(-1, 0) @staticmethod def down(): return Vector2(1, 0) @staticmethod def left(): return Vector2(0, -1) def get_elements(list_target, vect_pos, vect_dir, count): """ 获取指定位置上的·某个方向·指定数量的元素。 :param list_target: list :param r_index:列索引 :param c_index:行索引 :param r_dir:方向 :param c_dir:方向 :param count:次数--数量 :return: """ result = [] for item in range(count): vect_pos.x += vect_dir.x vect_pos.y += vect_dir.y result.append(list_target[vect_pos.x][vect_pos.y]) return result list01 = [ ["00", "01", "02", "03", "04"], ["10", "11", "12", "13", "14"], ["20", "21", "22", "23", "24"], ["30", "31", "32", "33", "34"], ["40", "41", "42", "43", "44"] ] print(get_elements(list01, Vector2(2, 0), Vector2.right(), 3))