day6面向对象
面向对象介绍(http://www.cnblogs.com/alex3714/articles/5188179.htm)
世界万物,皆可分类
世界万物,皆为对象
只要是对象,就肯定术语某种类
(1)特性 封装、继承、多态
Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工在九点钟开始工作,
他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”,
因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作。
多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定
class
object
(2)语法 属性、方法、构造函数、析构函数
私有方法,私有属性
创建类,并实例化两个对象
class Role(object): '''创建一个角色的类''' def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name #实例变量(静态属性) self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): #方法(动态属性) print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r2 = Role("jack","terroist","B15") #生成一个角色 r1.buy_gun("AK47")
把一个类变成一个具体对象的过程叫实例化。
__init__(self):构造函数,作用是在实例化时做一些类的初始化工作。
r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类与Role("alex","police","AK47")是一样的,赋给一个变量的目的是防止被销毁,python的内存回收机制,如果没有变量,开辟的内存将会被回收。
调用r1 = Role("alex","police","AK47")等价于Role(r1,"alex","police","AK47")其中,self相当于r1,把r1当做参数传进去了。
上面实例化过程中,self相当于r1,self.name等价于r1.name。每次实例化,都会把实例化的名字传进去,r1 = Role("alex","police","AK47") 》Role(r1,"alex","police","AK47"), r2 = Role("jack","terroist","B15")》Role(r2,"jack","terroist","B15")
r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类
r2 = Role("jack","terroist","B15") #生成一个角色
r1.buy_gun("AK47")
r2.get_shot() #调用r2相当于Role.get_shot(r2)
上面调用的过程中,r2.get_shot()相当于Role.get_shot(r2)。实例变量的作用域就是实例本身。
类中的函数叫方法;
类变量和实例变量的方法:
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) # r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 # r2 = Role("jack","terroist","B15") #生成一个角色 print(Role.n)
上面代码中,我们给类添加了一个变量n,可以发现,我们没有创建实例,就可以调用,说明n是存在类变量中的。
下面创建实例,看是否可以调用:
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r2 = Role("jack","terroist","B15") #生成一个角色 print(Role.n) print("r1.n:",r1.n)
上面,实例里面不包含n,但是也可以了,说明实例没有这个变量会去类里面找。
现在我们创建了一个name的类变量,由于实例里面也包含name属性。看是调用那个方法。
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r2 = Role("jack","terroist","B15") #生成一个角色 print(Role.n) print("r1.n:",r1.n) print("r1.name:",r1.name)
运行结果如下
123
r1.n: 123
r1.name: alex
从上面代码可以看出,先去实例里面找变量,如果没有才会去类中进行查找。
下面给类修改变量。
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r1.name = "chenronghua" #给实例修改名字 r2 = Role("jack","terroist","B15") #生成一个角色 r2.name = "小猪猪" #给实例重新进行赋值 print(Role.n) print("r1.n:",r1.n) print("r1.name:",r1.name)
运行结果如下:
123
r1.n: 123
r1.name: chenronghua
从上面可以看出,实例化之后,我们可以给实例化的变量重新赋值,修改里面的值。
下面我们给实例本身添加一个新的属性:
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r1.name = "chenronghua" r1.bullet_vests = True #属性不存在,重新创建一个属性 r2 = Role("jack","terroist","B15") #生成一个角色 r2.name = "小猪猪" print("bullet_vests",r1.bullet_vests) print("r2.bullet_vests:",r2.bullet_vests)
运行结果如下:
bullet_vests True
Traceback (most recent call last):
File "/home/zhuzhu/第六天/CF.py", line 29, in <module>
print("r2.bullet_vests:",r2.bullet_vests)
AttributeError: 'Role' object has no attribute 'bullet_vests
上面,我们给r1实例创建了一个bullet_vests的新属性,可以看出,能够给实例r1创建新的属性,创建的属性r2实例是不具备的。
下面来删除实例里面的变量:删除r1实例中的weapon
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r1.name = "chenronghua" del r1.weapon #删除实例r1中的weapon r2 = Role("jack","terroist","B15") #生成一个角色 r2.name = "小猪猪" print(r2.weapon) print(r1.weapon)
运行结果如下:
B15
Traceback (most recent call last):
File "/home/zhuzhu/第六天/CF.py", line 29, in <module>
print(r1.weapon)
AttributeError: 'Role' object has no attribute 'weapon
从运行结果可以看出,删除实例r1中的weapon之后,实例r2中的weapon不受影响,但是实例r1中的weapon不存在了。
如果我们删除Role类中的weapon,那么肯定r1.weapon和r2.weapon都不能调用。
下面来看一下,实例里面是否可以修改类变量:
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r1.name = "chenronghua" r1.n = "666可以改吗" #修改类中的变量,看是否可以成功 r2 = Role("jack","terroist","B15") #生成一个角色 r2.name = "小猪猪" print("r1.n:",r1.n) print("r2.n:",r2.n)
运行结果如下:
r1.n: 666可以改吗
r2.n: 123
从上面代码可以看出,r1.n="666可以改吗"等于在实例r1中重新创建了一个变量n,因为实例r1中不存在n,不影响类本身Role.n中的值。
类内存和类生成的实例内存。
类变量的用途?大家共用的属性,节省开销。比如防弹衣,默认是没有穿防弹衣的,我们可以在类中定义一个bullet_vests="",这样,每个人都具有了防弹衣的属性。当某人买了放单衣的时候,直接r1.bullet_vests=True即可。虽然可以在属性里面定义,但是这样每个属性里面都创建了bullet_vests,浪费了内存。在类中只需创建一次即可。
析构函数
析构函数:在实例释放、销毁的时候执行的,通常用于做一些收尾工作,如关闭一些数据库链接,打开的临时文件,可以在里面进行操作。
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def __del__(self): #不需要传参数,实例结束之后自动执行,不用调用直接执行 析构函数 print("%s 彻底死了" %self.name) def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r1.name = "chenronghua" r1.n = "666可以改吗" r2 = Role("jack","terroist","B15") #生成一个角色 r2.name = "不努力" r1.get_shot() r2.shot()
运行结果如下:
ah....,I got shot......
shotting.......
chenronghua 彻底死了
不努力 彻底死了
从上面代码可以看出,__del__析构函数在程序退出的时候自动执行。就是在我们运行玩类之后,自动销毁变量。是在所有调用结束不使用的时候才销毁的。
__del__析构函数不需要自己调用,在程序调用结束后自动执行。
私有方法,私有属性
私有方法,私有属性:就是只能内部访问,外部访问不了。
比如上面类中的self.life_value属性,我们知道,任何人执行程序都可以调用r1.life_value=0,直接让生命值变为0,如下:
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def __del__(self): #不需要传参数,实例结束之后自动执行,不用调用直接执行 print("%s 彻底死了" %self.name) def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r2 = Role("jack","terroist","B15") #生成一个角色 print("modify before:",r1.life_value) r1.life_value = 0 print("modify after:",r1.life_value)
运行结果如下:
modify before: 100
modify after: 0
alex 彻底死了
jack 彻底死了
从上面代码可以看出,开始的时候r1.life_value生命值是100满的,但是我们修改了生命值,直接让生命值变成0;可以看出,生命值直接改变了。假如是一款游戏的话,上来直接别人修改生命值就挂了,还没有摸过女生的屁股就死了,这他妈也太冤枉了吧。所以,这样肯定是不行的,不能让外部调用机密的属性,只能在内部进行调用。如下:
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.__life_value = life_value self.money = money # def __del__(self): #不需要传参数,实例结束之后自动执行,不用调用直接执行 # print("%s 彻底死了" %self.name) def show_status(self): print("name:%s weapon:%s life_value:%s" %(self.name,self.weapon,self.__life_value)) def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r2 = Role("jack","terroist","B15") #生成一个角色 print(r1.__life_value)
运行结果如下:
Traceback (most recent call last):
File "/home/zhuzhu/第六天/CF.py", line 30, in <module>
print(r1.__life_value)
AttributeError: 'Role' object has no attribute '__life_value'
从上面运行结果可以看出,当我们把变量life_value设置为私有变量__life_value的时候,外部是不能够调用的。错误提示是:Role类中没有__life_value属性。
既然私有属性不能在外部调用,那么我们就在程序内部调用。
class Role(object): '''创建一个角色的类''' n = 123 #类的变量,存在类的内存中 name = "我是类name" def __init__(self,name,role,weapon,life_value=100,money=15000): '''初始化变量''' self.name = name self.role = role self.weapon = weapon self.__life_value = life_value self.money = money # def __del__(self): #不需要传参数,实例结束之后自动执行,不用调用直接执行 # print("%s 彻底死了" %self.name) def show_status(self): '''通过内部调用私有属性''' self.__life_value -= 50 print("name:%s weapon:%s life_value:%s" %(self.name,self.weapon,self.__life_value)) def shot(self): print("shotting.......") def get_shot(self): print("ah....,I got shot......") def buy_gun(self,gun_name): print("%s just bougnt %s" %(self.name,gun_name)) r1 = Role("alex","police","AK47") #实例化,又可以称为初始化分类 r2 = Role("jack","terroist","B15") #生成一个角色 r1.show_status() #通过函数内部调用私有属性
运行结果如下:
name:alex weapon:AK47 life_value:50
上面代码,我们在类内部新增了一个方法,用来调用私有属性,可以看出,在内部是可以调用私有属性的。并且能够正常调用执行私有属性。
因此,私有属性是能够调用的,只是需要在程序内部执行。在外部是不能调用的。这种情况适用于很多时候,比如我们不希望别人查看我们的密码,银行账号,一些私有的属性,都可以通过设置这种私有属性的方法来规避。
也可以设置私有方法,只需要在前面添加__get_shot(self)就设置了一个私有方法,私有方法在外部是不能够调用的。