zoukankan      html  css  js  c++  java
  • 13-面向对象2

    保护对象的属性

    如果有一个对象,当需要对其进行修改属性时,有2钟方法:

    • 对象名.属性名 = 数据  ---->直接修改
    • 对象名.方法名()    ---->间接修改

    为了更好的保存属性的安全,即不能随意修改,一般的处理方式为:

    • 将属性定义为私有属性
    • 添加一个可以调用的方法,供调用
     11 class Person(object):       
     12     def __init__(self,name):
     13         self.__name = name  
     14     def getName(self):      
     15         return self.__name  
     16     def setName(self,newName):
     17         if len(newName)>=5: 
     18             self.__name = newName
     19         else:               
     20             print('error:名字的长度要大于或者等于5')
     21                             
     22 xiaoming = Person('XIAOYAFEI')                                                                      
     23 print(xiaoming.__name) 

    运行结果为:

    Traceback (most recent call last):
      File "test.py", line 23, in <module>
        print(xiaoming.__name)
    AttributeError: 'Person' object has no attribute '__name'

    修改代码:

     11 class Person(object):    
     12     def __init__(self,name):
     13         self.__name = name
     14     def getName(self):   
     15         return self.__name
     16     def setName(self,newName):
     17         if len(newName)>=5:
     18             self.__name = newName
     19         else:            
     20             print('error:名字的长度要大于或者等于5')
     21                          
     22 xiaoming = Person('XIAOYAFEI')
     23                          
     24 xiaoming.setName("wang") 
     25 print(xiaoming.getName())                                                                           
     26                          
     27 xiaoming.setName('lisisi')
     28 print(xiaoming.getName())

    运行结果:

    error:名字的长度要大于或者等于5
    XIAOYAFEI
    lisisi

    总结:

    • python中没有像C++中public和private这些关键字来区别公有属性和私有属性
    • 它是以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表示该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)

    __del__()方法

    创建对象后,python解释器默认调用__init__()方法;

    当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法

      1 #!/usr/bin/python
      2 #coding=utf8 
      3 """          
      4 # Author: xiaoyafei
      5 # Created Time : 2018-04-08 15:28:14
      6              
      7 # File Name: test2.py
      8 # Description:
      9              
     10 """          
     11 import time  
     12 class Animal():
     13     #初始化方法
     14     #创建为对象后会自动被调用
     15     def __init__(self,name):
     16         print('???????__init__方法被调用???????')
     17         self.__name = name
     18              
     19     #析构方法
     20     #当对象被删除时,会自动被调用
     21     def __del__(self):
     22         print('__del__方法被调用')
     23         print('%s对象马上被干掉了......'%self.__name)
     24              
     25 #创建对象    
     26 dog = Animal('嗨皮')
     27 #删除对象    
     28 del dog      
     29              
     30 cat = Animal('波斯猫')
     31 cat2 = cat   
     32 cat3 = cat   
     33              
     34 print('马上删除cat对象')
     35 del cat      
     36 print('马上删除cat1对象')
     37 del cat2     
     38 print('马上删除cat2对象')
     39 del cat3     
     40              
     41 print('程序在2秒钟后结束')
     42 time.sleep(2) 

    运行结果如下:

    ———————__init__方法被调用———————
    __del__方法被调用
    嗨皮对象马上被干掉了......
    ———————__init__方法被调用———————
    马上删除cat对象
    马上删除cat1对象
    马上删除cat2对象
    __del__方法被调用
    波斯猫对象马上被干掉了......
    程序在2秒钟后结束

    总结:

    • 当有1个变量保存了对象的引用时,此对象的引用计数就会加1
    • 当使用del删除变量指向的对象时,如果对象的引用计数不为1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除

    继承

    在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为狗和猫继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承自狗

    继承示例

    #!/usr/bin/python
    #coding=utf8
    """
    # Author: xiaoyafei
    # Created Time : 2018-04-04 11:35:02
    
    # File Name: 03-单继承.py
    # Description:
    
    """
    #定义一个父类
    class Cat():
        def __init__(self,name,color="白色"):
            self.name = name
            self.color = color
        def run(self):
            print('%s------在跑'%self.name)
    
    
    #定义一个子类,来继承Cat类
    class Bosi(Cat):
    
        def __str__(self):
            return self.name
        def setNewName(self,newName):
            self.name = newName
        def eat(self):
            print("%s------在吃"%self.name)
    
    bs = Bosi("lipeng")
    bs.run()
    bs.setNewName("小明")
    print(bs)

    运行结果为:

    lipeng------在跑
    小明

    说明:

    •   虽然子类没有定义__init__方法,但是父类有,所以在子类继承父类的时候这个方法就被继承了,所以只要创建Bosi对象,就默认执行了那个继承过来的父类的__init__方法

    总结:

    •   子类在继承的时候,在定义类时,小括号()中为父类的名字
    •    父类的属性、方法,会被继承给子类

    注意点

      1 #!/usr/bin/python
      2 #coding=utf8
      3 """
      4 # Author: xiaoyafei
      5 # Created Time : 2018-04-08 15:45:07
      6  
      7 # File Name: 04-单继承-注意点.py
      8 # Description:
      9  
     10 """
     11 class Animal():
     12     def __init__(self,name='动物',color='白色'):
     13         self.__name = name
     14         self.color = color
     15     def __test(self):
     16         print(self.__name)
     17         print(self.color)
     18     def test(self):
     19         print(self.__name)
     20         print(self.color)
     21  
     22 class Dog(Animal):
     23     def dogTest1(self):
     24         #print(self.__name)
     25         print(self.color)
     26     def dogTest2(self):
     27         #self.__test()
     28         self.test()
     29  
     30 A = Animal()
     31 #print(A.__name)         #程序出现异常,不能直接访问私有属性
     32 print(A.color)
     33 #A.__test()          #程序出现异常,不能直接访问私有方法                                                                                                                                                                                                          
     34 A.test()
     35  
     36 print('----------------------------华丽的分割线----------------------------------')
     37 D = Dog(name = '小花狗',color = '黄色')
     38 D.dogTest1()
     39 D.dogTest2()
    • 私有的属性,不能通过对象直接访问,但是可以通过方法访问
    • 私有的方法,不能通过对象直接访问
    • 私有的属性、方法,不会被子类继承,也不能给访问
    • 一般情况下,私有的属性、方法都是不对外公布的,往往来做内部的事情,起到安全的作用

    多继承

    所谓多继承,即子类有多个父类,并且具有它们的特征

    python中多继承的格式如下:

     14 class a():
     15     def printA(self):
     16         print('-aaaaaaaaaaaaa')
     17      
     18 class b():
     19     def printB(self):
     20         print('------------b')
     21       
     22      
     23 class c(a,b):
     24     def printC(self):
     25         print('-cccccccccccccccccc')
     26      
     27 c  =  c()
     28 c.printA()
     29 c.printB()
     30 c.printC()

    运行结果如下:

    -aaaaaaaaaaaaa
    ------------b
    -cccccccccccccccccc

    说明:

    • python中是可以多继承的
    • 父类中的方法、属性,子类会继承

    多继承-注意点

      1 #!/usr/bin/python
      2 #coding=utf8
      3 """  
      4 # Author: xiaoyafei
      5 # Created Time : 2018-04-04 14:29:20
      6      
      7 # File Name: 06-多继承注意点.py
      8 # Description:
      9     在多个父类中拥有相同的方法应该调用哪一个???
     10      
     11     可以使用__mro__方法去查看调用顺序                                                                                                                                                                                                                             
     12 """  
     13      
     14 class A():
     15     def printA(self):
     16         print('aaaaaaaaaaaaaaaaaa')
     17 class B():
     18      def printA(self):
     19          print('bbbbbbbbbbbbbbbbb')
     20      
     21 class S(A,B):
     22     def printS(self):
     23         print('SSSSSSSSSSSSSSSSSS')
     24      
     25 zi = S()
     26 zi.printS()
     27 zi. printA()
     28 print(S.__mro__)    #可以查看C类的对象搜索方法时的先后顺序

    运行结果:

    SSSSSSSSSSSSSSSSSS
    aaaaaaaaaaaaaaaaaa
    (<class '__main__.S'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

    重写父类方法和调用父类方法

    重写父类方法

    所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法

     13 class Cat():
     14     def sayHello(self):
     15         print('Hello----1')                                                                                                                                                                                                                                       
     16          
     17 class Bosi(Cat):
     18     def sayHello(self):
     19         print('Hello----4')
     20 bosi = Bosi()
     21 bosi.sayHello()

    运行结果如下:

    Hello----4

    调用父类方法

      1 #!/usr/bin/python
      2 #coding=utf8
      3 """
      4 # Author: xiaoyafei
      5 # Created Time : 2018-04-08 17:28:14
      6  
      7 # File Name: 08-调用父类的方法-1.py
      8 # Description:
      9  
     10 """
     11 class Cat():
     12     def __init__(self,name):
     13         self.name = name
     14         self.color = 'yellow'
     15      
     16 class Bosi(Cat):
     17     def __init__(self,name):
     18         super().__init__(name)
     19  
     20     def getName(self):
     21         return self.name
     22  
     23 bosi = Bosi('波斯猫')
     24 print(bosi.name)                                                                                                                                                                                                                                                  
     25 print(bosi.color)

    运行结果如下:

    波斯猫
    yellow

    super()不是父类,而是继承顺序的下一个类

    在多重继承是会涉及到继承顺序,super()相当于返回继承顺序的下一个类,而不是父类

    多态

    多态的概念是应用于Java和c#这一类强语言中,而python崇尚"鸭子类型"

    所谓多态:定义时的类型和运行时的类型不一样,此时就形成了多态

    python鸭子类型代码:

     12 class F1(object):
     13     def show(self):
     14         print('F1.show')
     15 class S1(F1):
     16     def show(self):
     17         print('S1.show')
     18 class S2(F1):
     19     def show(self):
     20         print('S2.show')
     21  
     22 def Func(obj):
     23     print(obj.show())
     24  
     25 s1_obj = S1()
     26 Func(s1_obj)
     27  
     28 s2_obj = S2()
     29 Func(s2_obj)   
  • 相关阅读:
    wxWidgets教程
    Unity游戏资源反解工具
    The Story About .NET Cross Platform UI Frameworks
    IMGUI
    Unity可编程管线的顶点光照Shader
    常用mac命令
    Vulkan相关资源
    Controlling fixed function states from materials/scripts in Unity
    Forward Rendering VS Deferred Rendering
    C#转PHP
  • 原文地址:https://www.cnblogs.com/xiaoyafei/p/8746363.html
Copyright © 2011-2022 走看看