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)   
  • 相关阅读:
    PAT 1010. 一元多项式求导 (25)
    PAT 1009. 说反话 (20) JAVA
    PAT 1009. 说反话 (20)
    PAT 1007. 素数对猜想 (20)
    POJ 2752 Seek the Name, Seek the Fame KMP
    POJ 2406 Power Strings KMP
    ZOJ3811 Untrusted Patrol
    Codeforces Round #265 (Div. 2) 题解
    Topcoder SRM632 DIV2 解题报告
    Topcoder SRM631 DIV2 解题报告
  • 原文地址:https://www.cnblogs.com/xiaoyafei/p/8746363.html
Copyright © 2011-2022 走看看