python学习第六周之面向对象编程

1.面向对象简单介绍,在学习面向对象的时候,我们会学习到以下内容:

特性:class、object;封装,继承,多态

语法:属性,方法,构造函数,析构函数,私有方法,私有属性,类变量,实例变量

2.面向对象特性介绍:

(1)类:class

一个类就是对一类拥有相同属性的对象的抽象、蓝图、原型;在类中定义了这些对象都具备的属性、共同方法。

(2)object对象:一个对象就是一个类的实例化后的实例。

(3)Encapsulation 封装:

  在类中对数据的赋值、内部调用,对外部对象是透明的;使类变成容器,包含类的数据和方法。

(4)Tnheritance 继承:

  一个类可以派生出子类,在父类定义的属性、方法自动被子类继承。

(5)Polymoyphism 多态:

  同一个基类派生出不同子类,每个子类在继承同样方法名的同时对父类方法做了不同的实现。

3.通过例子来看一下opp编程

(1)我们现在来看一个关于狗吠的例子:

class Dog:
    def __init__(self,name):
        self.name = name
    def bulk(self):
        print("%s:wang wang wang!" % self.name)
d1=Dog("一")   
d2=Dog("二")
d3=Dog("三")
d1.bulk()
d2.bulk()
d3.bulk()

 (2)下面我们通过cs游戏中创建两个角色,给这两个角色赋予不同的属性和方法,使其实现不同的功能。

class Role: #Role为类名
    def __init__(self, name, role, weapon, life_value=100, money=15000):
        #构造函数
        #在实例化时做一些类的初始化的工作
        self.name = name   #self.name赋给了实例,为实例变量(静态属性),作用域就是实例本身
        self.role = role
        self.weapon = weapon
        self.life_value = life_value   
self.money = money
def shot(self): #类的方法,即功能(动态属性) print("shooting...")
def got_shot(self): print("ah...,I got shot...") def buy_gun(self, gun_name): print("%s just bought %s" % (self.name,gun_name)) r1 = Role('wu', 'police','AK47') #生成一个角色,相当于Role(r1,'Alex', 'police','AK47')
#实例化:初始化一个类,相当于造了一个对象;把一个类变成一个具体对象的过程为实例化 r2 = Role('Jack', 'terrorist', 'B22') # 生成一个角色;r2又叫为Role的实例 r1.buy_gun("b51") #内部实际是Role.buy_gun(r1) 类Role中的self接受的实际是self方法

   def __init__(self):是构造函数,作用:在实例化时做一些类的初始化的工作

  在以上cs例子中,如果我们只定义了类跟方法,没有实例化、没有调用,那么类在函数中也是存在的,可以通过打印类名来验证一下

    def buy_gun(self, gun_name):
        print("%s just bought %s" % (self.name,gun_name))
print(Role)   #函数没有调用,但是在内存中是存在的

   输出结果为 <class '__main__.Role'>

  实际上,r1 = Role('wu', 'police','AK47')实例化时,我们将r1一起传入内存中,所以这里我们实例化时实际是r1=Role(r1,'Alex', 'police','AK47')

  如r1.buy_gun("b51")  ,内部实际是Role.buy_gun(r1)  ,类Role中的self接受的实际是self方法

  got_shot、buy_gun等方法使保存在类的属性中的,需要的时候调用即可。

4.实例变量与类变量

(1)我们还是以cs游戏来说明实例变量与类变量。

在构造函数中,self.name=name,为实例变量,self.name赋给了实例,为实例变量(静态属性),作用域就是实例本身;

类变量不在构造函数中,直接写在类Role下面;

def shot(self):   #类的方法,即功能(动态属性)

r2 = Role('Jack', 'terrorist', 'B22')      #  生成一个角色;实例化;r2又叫为Role的实例

(2)我们在类Role中定义类变量 n,并可打印

  A.没有实例化对象,类变量可以打印

class Role: #Role为类名
    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
print(Role.n)    #类的变量存在类的内存中,还没有实例化便可以打印

   B.实例化对象后,类变量仍然可打印

print(Role.n)   
r1 = Role('Alex', 'police', 'AK47')
print(r1.n,r1.name) 
r2 = Role('Jack', 'terrorist', 'B22') 
print(r2.n,r2.name) 

   C.增加与实例变量相同的类变量,name="我是类name",发现输出结果与B中一样;这时得出结论:实例化时先找实例本身,如果实例本身没有,就去类里面找,比如n,在实例变量中没有,类变量里面有,就找到了n=123。

(3)实例变量与类变量的增删改

   修改r1与r2的名字:

r1 = Role('Alex', 'police', 'AK47')
r1.name="wu"   #修改实例变量中的name
print(r1.n,r1.name)

r2 = Role('Jack', 'terrorist', 'B22')
r2.name="徐"
print(r2.n,r2.name)

   在实例化后添加一个新的属性:

r1 = Role('Alex', 'police', 'AK47')
r1.name="wu"   #修改实例变量中的name
r1.bullet_prove=True   #添加一个新的属性,穿防弹衣
print(r1.n,r1.name,r1.bullet_prove)   #先找实例本身,如果实例本身没有,就去类里面找;
#比如n,在实例变量中没有,类变量里面有,如果找到了n=123

   在实例化后删除一个属性:

print(r1.weapon)
del r1.weapon  #删除一个属性
print(r1.weapon)

   修改类变量n:其实r1.n是在r1内存中增加了一个变量n;改变的不是类变量,在r2中没有变量n,所以在r2中打印类变量,结果为123;

r1.n="改类变量"   #其实是在r1的内存中 增加了一个变量n,n为“改类变量”;在这里改变的不是类变量
print("r1:",r1.weapon,r1.n)
print("r2:",r2.weapon,r2.n)
print(Role.n)  #打印类变量中的n,输出结果仍为123

Role.n="ABC" #在实例化r1,r2后,修改类变量n的值,打印发现 r1.n为 改类变量;r2.n为 ABC
print(r1.n,r2.n)     

   在类变量中增加一个n的列表n_list:r2.n_list与Role.n_list输出结果一样,因为form r1与from r2都是保存在类的内存n_list

class Role: #Role为类名
    n=123   #类变量
    name="我是类name"
    n_list=[]
  ...   ... r1 = Role('Alex', 'police', 'AK47') r1.n_list.append("from r1") r2 = Role('Jack', 'terrorist', 'B22') r2.n_list.append("from r2") print("r2:",r2.name,r2.n,r2.n_list) print(Role.n_list)

 5.类变量的作用即析构函数

(1)类变量:大家共同的属性,节省了开销。

(2)析构函数:在实例释放/销毁时自动执行,通常用于收尾工作;比如关闭数据库连接、关闭打开的临时文件。

  还是以cs游戏为例,在类Role中写一个析构函数:

    #析构函数
      def __del__(self):
         print("%s 完。。。。" % self.name)

   我们现在来体验一下析构函数:

r1 = Role('Alex', 'police','AK47')
r1.buy_gun("AK47")
r1.got_shot()   #程序退出时,会执行析构函数;所以在两个角色都运行完成后,才执行析构函数,退出
r2 = Role('Jack', 'terrorist', 'B22')
r2.got_shot()

   我们现在来看一下打印结果为:

Alex just bought AK47
ah...,I got shot...
ah...,I got shot...
Alex 完。。。。
Jack 完。。。。

   对象、实例释放或销毁的时候自动执行;所以析构函数最后执行,是因为两个角色都运行完成后,程序退出,析构函数执行;

  如果我们不想等到程序退出时执行析构函数,我们可以将r2实例化前删除r1

r1 = Role('Alex', 'police','AK47')
r1.buy_gun("AK47")
r1.got_shot()   #程序退出时,会执行析构函数;所以在两个角色都运行完成后,才执行析构函数,退出
del r1           #如果删除角色r1的话,为销毁程序,所以销毁程序后,会执行析构函数
r2 = Role('Jack', 'terrorist', 'B22')
r2.got_shot()

   打印结果为:

Alex just bought AK47
ah...,I got shot...
Alex 完。。。。
ah...,I got shot...
Jack 完。。。。

 6.私有方法与私有属性

私有属性一般分为动态属性(方法)跟静态属性(变量),一般认为私有属性就是变量。

(1)将构造函数中的变量修改为私有属性,在变量名前加__,这时外部无法访问

self.__life_value = life_value  
 #'__life_value'  为私有属性,私有属性在内部可以访问跟修改,如在函数中修改,发现输出结果修改

   如下,在访问是会报错,输出结果会报错“'Role' object has no attribute '__life_value'”

r1 = Role('Alex', 'police','AK47')
print(r1.__life_value)  

 如果我们要访问私有属性,要在类Role中定义一个 show_status() 方法:

#定义访问私有属性的方法
    def  show_status(self):
        print("name:%s weapon:%s life_val:%s" %(self.name,self.weapon,self.__life_value))

   这时便可以通过show_status方法来访问了:

r1 = Role('Alex', 'police','AK47')
print(r1.show_status())   #访问私有属性

 我们可以在内部对私有属性进行修改,在got_shot()属性中可以进行修改,这时再次通过show_status方法访问,发现life_value的值减少50

    def got_shot(self):
        self.__life_value -=50  #私有变量
        print("ah...,I got shot...")

 (2)同样的,修改某个方法为私有方法也是一样,在函数名前面加__,

    def __shot(self):   #类的方法,即功能(动态属性)  #加上__为私有方法,在外面无法访问,执行r1.__shot() 会报错
        print("shooting11...")

   在外面访问时会报错: 'Role' object has no attribute '__shot'

r1 = Role('Alex', 'police','AK47')
r1.__shot()    #__shot为私有方法,无法访问

 

这篇文章先写到这里,内容有点多,下次还是要分开写比较好,关于继承跟多态下一篇文章再会。

 

 

 

posted @ 2019-09-06 17:27  凸凸yolotheway  阅读(157)  评论(0编辑  收藏  举报