面向对象
一、引子 人狗大战
def person(name,sex,agger,hp): person_dic = {"name":name,"sex":sex,"agger":agger,"hp":hp} def attack(dog): #dog("xiaogei","shachai",260,1000000) # dog["hp"] -= person_dic["agger"] print("%s打了%s,%s掉了%s血" % (person_dic["name"],dog["name"],dog["name"],person_dic["agger"])) person_dic["attack"] = attack return person_dic def dog(name,kind,agger,hp): dog_dic = {"name":name,"kind":kind,"agger":agger,"hp":hp} def bite(person): #person_dic person["hp"] = person["hp"] - dog_dic["agger"] print("%s咬了%s,%s掉了%s血" % (dog_dic["name"], person["name"], person["name"],dog_dic["agger"])) dog_dic["bite"] = bite return dog_dic hei = dog("xiaohei","shachai",260,1000000) #字典hei = dog_dic = {"name":xiaohei,"kind":shachai,"agger":260,"hp":1000000,"bite":bite} alex = person("alex","men",250,100000) #字典alex = person_dic ={"name":lex,"sex":men,"agger":250,"hp":100000,"attack":attack} alex["attack"](hei) hei["bite"](alex) #bite(alex) #person_dic
二、理论知识
1.类:是一类具有相同属性和方法的事物 2.对象:是类中一个具体的具有自己属性值的,即事例 class Person: #类名 role = "人" #类的静态变量 是所有的对象共享的一个属性 类名.属性名调用的 def attack(self):pass #行为方法 print(Person.role) #类提供给我们的调用方式 print(Person.attack) #<function Person.attack at 0x000002937FDD8950> Person.role = "中国人" print(Person.role) #可以改变类的变量 print(Person.__dict__) #存储方式 print(Person.__dict__["role"]) print(Person.__dict__['attack']) 3.类只有两个作用: (1)使用类中的名字: 查看类中的名字: 类名.变量名 # 可以修改变量的值 类名.__dict__['变量名'] # 不能修改 (2)创造对象 实例化对象 对象就是实例,一个实际的例子 对象 = 类名() 4.对象的具体: 内存地址的不一致 不同的对象 属性的值应该不同 5.类名(参数) (1)创造一个空对象 : self (2)调用__init__方法 : 初始化方法 (3)把参数传给__init__方法 (4)完成init方法中的代码 (5)自动将self返回给实例化的地方 6.self就是对象 7.调用类中的方法 : 类名.方法名(对象) 对象名.方法名() 8.做题思路: 1.完成类 2.首先分析一下角色和类,类里面有哪些属性__init__方法 3.再分析这个类中能有哪些行为,定义为方法 4.实例化 传参数获取实例化之后的对象 首先创造对象====类() 执行init方法 5.对象的调用 使用对象调用,对象属性,和类中的方法 6.对象名的作用: 1.使用变量 对象名.属性名 2.调用方法 对象名.方法名()
三,创建类
class Person: role = "人" def __init__(self,name,sex,agger,hp): self.name = name self.sex = sex self.agger = agger self.hp = hp def attack(self): print(self.name) print(self.sex) obj1 = Person("alex","female",250,1) obj2 = Person("egon","mele",500,2) print(obj1.name,obj1.sex,obj1.agger,obj1.hp) print(obj2.name,obj2.sex,obj2.agger,obj2.hp) print(obj1.__dict__) print(obj2.__dict__) Person.attack(obj1) #通过类调用一个类中的方法 obj1.attack() #通过对象掉用了类中的方法
class Dog: role = "dog" def __init__(self,name,kind,agger,hp): self.name = name self.kind = kind self.agger = agger self.hp = hp def attack(self): print(self.name) print(self.kind) obj3 = Dog("dog","taidi",260,10000) print(obj3.name,obj3.kind,obj3.agger,obj3.hp)
class Person: #类名 role = '人' #类的静态变量 是所有的对象共享的一个属性 def __init__(self,name,sex,agger,hp): #方法 动态属性 内置的双下方法 self.name = name #对象属性 实例属性 self.sex = sex self.agger = agger self.hp = hp def attact(self,dog): #自定义方法 dog.hp -= self.agger print("%s打了%s,%s掉了%s血,还剩%s血"%(self.name,dog.name,dog.name,self.agger,dog.hp)) class Dog: def __init__(self,name,kind,agger,hp): self.name = name self.kind = kind self.agger = agger self.hp = hp def bite(self,person): person.hp -= self.agger print("%s咬了%s,%s掉了%s血,还剩%s血"%(self.name,person.name,person.name,self.agger,person.hp)) hei = Dog("小黑","teddy",260,10000) #调用一个Dog类,此时的hei和self一样,实例化:先创造对象 再初始化 alex = Person("alex","male",2,500) #实例化 alex.attact(hei) #Person.attact(alex,hei) hei.bite(alex) #Dog.bite(hei,alex)
总结做题思路:
1.完成类 2.首先分析一下角色和类,类里面有哪些属性__init__方法 3.再分析这个类中能有哪些行为,定义为方法 4.实例化 传参数获取实例化之后的对象 首先创造对象====类() 执行init方法 5.对象的调用 使用对象调用,对象属性,和类中的方法 6.对象名的作用: 1.使用变量 对象名.属性名 2.调用方法 对象名.方法名()
1.求圆的面积,圆的周长
from math import pi class Circle: def __init__(self, r): self.r = r def area(self): return pi * self.r ** 2 def perimeter(self): return 2 * pi * self.r c = Circle(5) print(c.r) #5 print(c.area()) #78.53981633974483 print(c.perimeter()) #31.41592653589793
2.面向对象编程,打印:
小明,男,10岁,上山去砍柴
小明,男,10岁,开车去东北
小明,男,10岁,最爱大保健
老张,男,90岁,上山去砍柴
老张,男,90岁,开车去东北
老张,男,90岁,最爱大保健
老王,男,70岁,上山去砍柴
....
class Preson: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def clib(self): print("%s,%s,%s岁,上山去砍柴"%(self.name,self.sex,self.age)) def drive(self): print("%s,%s,%s岁,开车去东北" %(self.name,self.sex,self.age)) def hobby(self): print("%s,%s,%s岁,最爱大保健" % (self.name,self.sex, self.age)) obj1 = Preson("xiaoming","men",10) obj1.clib() obj1.drive() obj1.hobby() obj2 = Preson("zhang","men",10) obj2.clib() obj2.drive() obj2.hobby()
四、理论知识
1.上帝视角 面向对象的特点 : 可扩展性强 相对控制性弱(结局不可控) (关系复杂,大) 面向过程的特点 : 比较容易想 可扩展性弱 (关系单一,小) 2.什么是类 什么是对象 什么是实例 ? 类 是一类具有相同属性和方法的事物 对象 是类中一个具体的具有自己的属性值的,即实例 3.与实际例子结合的理论知识 class Foo: #__init__ 内置初始化方法 def __init__(self): self.name = "alex" # 静态属性(静态变量) # 静态属性 = "中国" #是直接可以用类名。属性名调用的 #动态属性(动态方法)(函数) def attack(self):pass def bite(self):pass # 实例化:创造对象 执行init方法 # 对象 = 类名() print(对象.__dict__)
五、命名空间
1.由于对象和类之间存在一个关联关系,所以对象能够找到类,但是类不能找到对象
2.使用类名.属性 只会寻找类中的静态变量名字
3.使用对象.属性 会现在对象自己的命名空间中找名字。如果找不到 再到类的内存空间中去找
4.类名.静态变量 对象.属性名
5.类名可以调用对象的属性嘛? 不可以
6.对象可以调用类的属性嘛? 可以
class Person: Country = "中国人" #静态变量 print(Person.Country) #调用类中的变量 alex = Person() #创建一个空的命名空间 alex.name = "alex" #对象的属性 alex.Country = "泰国人" #对象调用了类的属性 print(alex.Country) #泰国人 egon = Person() #创建一个空的命名空间 egon.name = "egon" #对象调用了类的属性 egon.Country = "中国人人" #在自己的命名空间创建了一个属性 print(egon.Country) #中国人人
命名空间的例子1: class Person: Country = "中国人" alex = Person() egon = Person() print(alex.Country) #中国人(类在自己的命名空间没有找到Country这个属性名,所以调用了类中的静态变量名字) alex.Country = "印度人" #在对象的命名空间中创建了一个Country属性名 print(alex.Country) #印度人,(在对象自己的命名空间找到了Country这个属性名) print(Person.Country) #中国人,(类中的静态变量名字不会被对象改变) # 总结:只要你使用静态变量,就用类名去调用
命名空间的例子2:使用内存地址去分析 class Person: money = 0 mother = Person() father = Person() mother.money = mother.money + 100 father.money = father.money + 100 print(mother.money,id(mother.money)) #100,1718057536指向类中静态变量的内存地址 print(father.money,id(father.money)) #100,1718057536指向类中静态变量的内存地址 print(Person.money,id(Person.money)) #0 , 1718054336 不会改变类中静态变量的内存地址
命名空间的例子3:使用内存地址去分析 class Person: money = [0] mather = Person() father = Person() mather.money[0] = mather.money[0] + 100 print(mather.money[0],id(mather.money[0])) #100 1718057536 改变的是类中静态变量中第一个元素,对静态变量没有影响 father.money[0] = father.money[0] + 100 print(mather.money[0],id(mather.money[0])) #200 1718060736 改变的是类中静态变量中第一个元素,对静态变量没有影响 print(father.money[0],id(father.money[0])) #200 1718060736 改变的是类中静态变量中第一个元素,对静态变量没有影响 print(Person.money,id(Person.money)) #[200] 1763572885832 类.静态变量 的内存地址不会改变
命名空间的例子4:使用内存地址去分析 class Person: money = [0] mother = Person() father = Person() mother.money = [1000] father.money = [2000] print(mother.money,id(mother.money)) #[1000] 2670227728648 ,在自己的命名空间创建了一个money属性 print(father.money,id(father.money)) #[2000] 2670226915976 ,在自己的命名空间创建了一个money属性 print(Person.money,id(Person.money)) #[0] 2670226916104
写一个类,能统计这个类被多少个对象实例化了.所有的对象共享这个结果 init 静态变量 class Foo: num = 0 def __init__(self): Foo.num += 1 f1 = Foo() print(f1.num) #1 f2 = Foo() print(f2.num) #2 f3 = Foo() print(f3.num) #3 print(Foo.num)
六、组合
1.理论知识:
组合 两个类的事儿
什么叫组合 : 一个类对象的属性 是 另外一个类的对象
两个类的事儿 :类与类之间有一种"什么有什么的关系"
例子1:求圆环的周长和圆环的面积 圆的类,圆环也是一个类 属性 大圆半径 和 小圆半径 方法 面积 和 周长 from math import pi class Circle: def __init__(self,r): self.r = r def area(self): return self.r ** 2 * pi def perimeter(self): return 2 * pi * self.r c = Circle(5) class Ring: def __init__(self,outer,inner): self.outer = Circle(outer) #对象的属性 = 类的对象---->组合 self.inner = Circle(inner) def area(self): return self.outer.area() - self.inner.area() def perineter(self): return self.outer.perimeter() + self.inner.perimeter() r = Ring(10,5) print(r.area()) #235.61944901923448 print(r.perineter()) #94.24777960769379
例子2: 老师 name sex course(课程) birth class Birthday: def __init__(self,year,month,day): self.year = year self.month = month self.day = day class Teacher: def __init__(self,name,sex,course,birth): self.name = name self.sex = sex self.course = course self.birth = birth #birth是一个对象 birth = Birthday(1960,3,7) alex = Teacher("alex","male","python",birth) my_birth = alex.birth import time if my_birth.month == time.localtime().tm_mon\ and my_birth.day == time.localtime().tm_mday: print("生日快乐") else: print("今天不是此人生日") print("他的生日是%s月%s日今年%s岁"%(my_birth.month, my_birth.day,time.localtime().tm_year - my_birth.year)) print(alex.name,alex.sex,alex.course,my_birth.year,my_birth.month,my_birth.day)
例子3:人狗大战 class Weapon: def __init__(self,name,price,agger,protect): self.name = name self.price = price self.agger = agger self.protect = protect def kill(self,dog): print("使用了%s的必杀技,打中了%s"%(self.name,dog.name)) dog.hp = dog.hp - self.agger print("%s的生命值减少了%s,剩余%s"%(dog.hp,self.agger,dog.hp)) class Person: def __init__(self,name,sex,agger,hp): self.name = name self.sex = sex self.agger = agger self.hp = hp def attact(self,dog): dog.hp = dog.hp - self.agger return "%s打了%s,%s掉了%s血,还剩%s血"%(self.name,dog.name,dog.name,self.agger,dog.hp) class Dog: def __init__(self,name,kind,agger,hp): self.name = name self.kind = kind self.agger = agger self.hp = hp def bite(self,person): person.hp = person.hp - self.agger return "%s打了%s,%s掉了%s血,还剩%s血"%(self.name,person.name,person.name,self.agger,person.hp) weapon = Weapon("属龙宝刀",20000,999,0) print(weapon.name) alex = Person("alex","men",1,250) hei = Dog("dog","teddy",260,10000) print("欢迎登陆xxxx") print(hei.bite(alex)) ret1 = input("输入1:充值,并且可以复活 2:退出游戏") if ret1 == "2": exit() elif ret1 == "1": money = int(input("10000元可以复活一次,你要充值多少元")) if money > 10000: alex.hp = 250 alex.money = money - 10000 print("复活成功,当前血量%s,当前帐户余额%s"%(alex.hp,alex.money)) ret2 = input("输入1:购买武器") if ret2 == "1": if alex.money >= 2000: alex.money -= weapon.price print(111) alex.weap = weapon #对象的属性 是 另一个类的对象 print("购买成功,当前余额%s,当前武器%s"%(alex.money,alex.weap.name)) print(alex.attact(hei)) #alex打了dog,dog掉了1血,还剩9999血 alex.weap.kill(hei) hei.bite(alex)