#coding:utf-8 #类具有:封装、继承、多态,三个特性 ''' 封装:可以理解为私有的,别人不可以访问的内容 继承:子类可以继承多个父类的特性,除了父类的特性外也可以增加或修改某一些自己的特性 多态:父类也可以访问子类的某些特性 作用: 1.封装可以隐藏实现细节,使得代码模块化 2.继承可以拓展已经存在的代码模块(类),目的都是为了代码重用 3.多态是为了实现接口重用,例如类在继承和派生的时候,保证使用"家族"中任一类的实例的某一属性的正确调用 注意:Python不支持多态 但是通过Python可以模拟多态 ''' class Role(object): #object基类 # name = None #这样也可以定义属性叫做类变量,它是一个公共的变量,它同样可以在函数中用self.name来调用,但是在初始化时候不能够像__init__函数里面一样的传参 #类变量, 不需要初始化, 当类存入内存中时, 就已经生成了 ac = None def __init__(self,name,role,weapon,life_value): #__init__初始化方法() # self表示实例本身 self.name = name #self.name定义实例变量,只在实例内有效,当初始化了这个方法后,实例变量才会生效 self.role = role self.weapon = weapon self.life_value = life_value def buy_weapon(self,weapon): self.weapon = weapon print("%s is buying [%s]"%(self.name,weapon)) p1 = Role("alex","Police",'b10',100) #p1是Role的实例,相当于(p1,name,role,weapon,life_value) t1 = Role('eric','Terrorist','B11',100) t2 = Role('t2','Terrorist','B12',100) t3 = Role('t3','Terrorist','B13',100) p1.ac = "china bor" t1.ac = "tw bor" Role.ac = "DD" #这样修改Role.ac里面的变量值,会影响到p1.ac和t1.ac实例变量吗? print("P1:",p1.ac) #P1: china bor print("t1:",t1.ac) #t1: tw bor print("t2:",t2.ac) #t2: DD print("t3:",t3.ac) #t3: DD print(Role.ac) #DD # 结果显示:Role.ac没有影响到p1和t1实例变量 # 因为p1和t1赋值ac变量后他们已经是两个完全独立存在于内存中的数据,和Role.weapon没有关系 # Role.ac = "DD" 相当于在Role这个实例中重新赋值一个weapon变量,值为"DD" #t3和t4 = "DD" 是因为它们没有ac这个值,当然会去Role这个类里面去找对应的值 #===================================================================== # #类变量的作用 # #例子:查看初始化函数的调用次数 class Role(object): members = 0 #定义一个类变量 def __init__(self,name,role,weapon,life_value): self.name = name self.role = role self.weapon = weapon self.life_value = life_value Role.members += 1 #每调用初始化函数一次,类变量就加1 def buy_weapon(self,weapon): # 类里面的函数不会单独存储于每个实例中 # 1.因为当实例调用类里面函数时,类函数需要验证是哪个实例调用它,如果类函数存放在实例中显然是无用的 # 2.如果每个实例中都存放一份类函数,那么实例可想而知会非常的庞大,也不符合设计原则 # 3.如果在类函数中不传入实例(self)做验证,当前类函数它会不知道是谁在调用它 #buy_weapon(self)这个类函数中的self,就是当前调用类函数的实例(p1,t1等),实例传入buy_weapon(self)类函数中做验证 self.weapon = weapon print("%s is buying [%s]"%(self.name,weapon)) p1 = Role("alex","Police",'b10',100) t1 = Role('eric','Terrorist','B11',100) t2 = Role('t2','Terrorist','B12',100) t3 = Role('t3','Terrorist','B13',100) p1.ac = "china bor" t1.ac = "tw bor" Role.ac = "DD" print(Role.members) #查看调用了多少次初始化函数 #===================================================================== #多态 #多态是为了实现接口重用,例如类在继承和派生的时候,保证使用"家族"中任一类的实例的某一属性的正确调用 #注意:Python不支持多态,但是通过Python可以模拟多态 #例子: ''' 1.有Cat和Dog两个类,它们共同继承于Animal这个基类 2.Cat和Dog都有一个talk方法 问题: 1.当我们调用talk方法时,必须先创建Cat或Dog对象,才能实例化里面的talk方法 2.如果我们需要一个统一的接口来实现调用talk方法呢? 例如:怎样把接口统一为Animal().talk呢? Animal(Dog对象或Cat对象).talk() 根据你对象的不同,分别调用不同对象里的talk方法 ''' class Animal(object): hobbie = "meat" def __init__(self,name): self.name = name def talk(self): raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): #重写基类的talk方法 return "Menow!" class Dog(Animal): def talk(self): #重写基类的talk方法 return 'woof! woof!' 定义统一talk接口(方法一) animals = [Cat("Missy"),Dog("Lassie")] #创建Cat和Dog类的对象,放入列表 for animal in animals: #循环列表里面的对象,赋值给一个变量(变量名字就是接口名称),然后分别调用对象里的talk方法 print(animal.name + ":" + animal.talk()) 定义统一talk接口(方法二) def animal_talk(obj): print(obj.talk()) animal_talk(Dog("Missy")) animal_talk(Cat("Missy")) d = Dog("Missy") c = Cat("Lassie") print(d.hobbie)