• 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为私有方法,无法访问
    

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

     

  • 相关阅读:
    java fx example
    JavaFX 2.0+ WebView /WebEngine render web page to an image
    剑指Offer面试题41(Java版):和为s的两个数字VS和为s的连续正数序列
    时间类(时间戳的各种转换成)
    Android系统各种类型的service刨根解读
    二叉树的建立基本操作(链表方式)(一)
    从头认识java-13.2 利用元组的方式返回多类型对象
    EA初步使用
    inline-block元素设置overflow:hidden属性导致相邻行内元素向下偏移
    下拉框与列表框
  • 原文地址:https://www.cnblogs.com/wuxiaoru/p/11474991.html
Copyright © 2020-2023  润新知