02_python基础(面向对象编程)

系统 1377 0

面向对象编程: 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization)和泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派。

面向对象思想三大要素:封装,继承和多态。

1   定义使用类  

            
              class
            
            
               Student(object):

    
            
            
              #
            
            
               __init__是一个特殊方法用于在创建对象时进行初始化操作
            
            
              #
            
            
               通过这个方法我们可以为学生对象绑定name和age两个属性
            
            
              def
            
            
              __init__
            
            
              (self, name, age):
        self.name 
            
            =
            
               name
        self.age 
            
            =
            
               age

    
            
            
              def
            
            
               study(self, course_name):
        
            
            
              print
            
            (
            
              '
            
            
              %s正在学习%s.
            
            
              '
            
             %
            
               (self.name, course_name))

    
            
            
              #
            
            
               PEP 8要求标识符的名字用全小写多个单词用下划线连接
            
            
              #
            
            
               但是部分程序员和公司更倾向于使用驼峰命名法(驼峰标识)
            
            
              def
            
            
               watch_movie(self):
        
            
            
              if
            
             self.age < 18
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s只能观看海贼王
            
            
              '
            
             %
            
               self.name)
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s正在观看动漫
            
            
              '
            
             %
            
               self.name)

test 
            
            = Student(
            
              "
            
            
              非常君
            
            
              "
            
            , 18
            
               )
test.study(
            
            
              "
            
            
              python
            
            
              "
            
            
              )
test.watch_movie()
            
          

2  访问可见性问题

  在Python中,属性和方法的访问权限只有两种,也就是公开的和私有的, Python 中将成员和方法私有化的方式是在成员名或者方法名前面加两个下划线 ,Python 中访问私有成员变量的正确方式为:实例类. 类名_ 变量名   (不建议使用)

            
              class
            
            
               PrivateTest:
    
            
            
              __name
            
             = 
            
              "
            
            
              private
            
            
              "
            
            
              if
            
            
              __name__
            
             == 
            
              "
            
            
              __main__
            
            
              "
            
            
              :
    pt 
            
            =
            
               PrivateTest()
    
            
            
              print
            
            (pt._PrivateTest__name)
          

在实际开发中,我们并不建议将属性设置为私有的,因为这会导致子类无法访问(后面会讲到)。所以大多数Python程序员会遵循一种命名惯例就是让属性名以单下划线开头来表示属性是受保护的,本类之外的代码在访问这样的属性时应该要保持慎重。这种做法并不是语法上的规则,单下划线开头的属性和方法外界仍然是可以访问的,所以更多的时候它是一种暗示或隐喻。

Python内置的 @property 装饰器就是负责把一个方法变成属性调用的。我们之前的建议是将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问,那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作。如果要做到这点,就可以考虑使用@property包装器来包装getter和setter方法,使得对属性的访问既安全又方便

            
              class
            
            
               Person(object):

    
            
            
              def
            
            
              __init__
            
            
              (self, name, age):
        self._name 
            
            =
            
               name
        self._age 
            
            =
            
               age

    
            
            
              #
            
            
               访问器 - getter方法
            
            
                  @property
    
            
            
              def
            
            
               name(self):
        
            
            
              return
            
            
               self._name

    
            
            
              #
            
            
               访问器 - getter方法
            
            
                  @property
    
            
            
              def
            
            
               age(self):
        
            
            
              return
            
            
               self._age

    
            
            
              #
            
            
               修改器 - setter方法
            
            
                  @age.setter
    
            
            
              def
            
            
               age(self, age):
        self._age 
            
            =
            
               age

    
            
            
              def
            
            
               play(self):
        
            
            
              if
            
             self._age <= 16
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s正在玩飞行棋.
            
            
              '
            
             %
            
               self._name)
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s正在玩斗地主.
            
            
              '
            
             %
            
               self._name)



            
            
              def
            
            
               main():
    person 
            
            = Person(
            
              '
            
            
              王大锤
            
            
              '
            
            , 12
            
              )
    person.play()
    person.age 
            
            = 22
            
              
    person.play()
    
            
            
              #
            
            
               person.name = '白元芳'  # AttributeError: can't set attribute
            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    main()
            
          

__slots__魔法

我们讲到这里,不知道大家是否已经意识到,Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

            
              class
            
            
               Person(object):

    
            
            
              #
            
            
               限定Person对象只能绑定_name, _age和_gender属性
            
            
              __slots__
            
             = (
            
              '
            
            
              _name
            
            
              '
            
            , 
            
              '
            
            
              _age
            
            
              '
            
            , 
            
              '
            
            
              _gender
            
            
              '
            
            
              )

    
            
            
              def
            
            
              __init__
            
            
              (self, name, age):
        self._name 
            
            =
            
               name
        self._age 
            
            =
            
               age

    @property
    
            
            
              def
            
            
               name(self):
        
            
            
              return
            
            
               self._name

    @property
    
            
            
              def
            
            
               age(self):
        
            
            
              return
            
            
               self._age

    @age.setter
    
            
            
              def
            
            
               age(self, age):
        self._age 
            
            =
            
               age

    
            
            
              def
            
            
               play(self):
        
            
            
              if
            
             self._age <= 16
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s正在玩飞行棋  %s.
            
            
              '
            
             %
            
              (self._name, self._gender))
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s正在玩斗地主 %s 
            
            
              '
            
             %
            
              (self._name, self._gender))



            
            
              if
            
            
              __name__
            
             == 
            
              "
            
            
              __main__
            
            
              "
            
            
              :
    person 
            
            = Person(
            
              '
            
            
              王大锤
            
            
              '
            
            , 22
            
              )
    person._gender 
            
            = 
            
              '
            
            
            
              '
            
            
              
    person.play()
            
          

3   静态方法和类方法

之前,我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息。实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法很显然就不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以这个方法是属于三角形类而并不属于三角形对象的。我们可以使用静态方法来解决这类问题,代码如下所示。

            
              from
            
             math 
            
              import
            
            
               sqrt



            
            
              class
            
            
               Triangle(object):

    
            
            
              def
            
            
              __init__
            
            
              (self, a, b, c):
        self._a 
            
            =
            
               a
        self._b 
            
            =
            
               b
        self._c 
            
            =
            
               c

    @staticmethod
    
            
            
              def
            
            
               is_valid(a, b, c):
        
            
            
              return
            
             a + b > c 
            
              and
            
             b + c > a 
            
              and
            
             a + c >
            
               b

    
            
            
              def
            
            
               perimeter(self):
        
            
            
              return
            
             self._a + self._b +
            
               self._c

    
            
            
              def
            
            
               area(self):
        half 
            
            = self.perimeter() / 2
        
            
              return
            
             sqrt(half * (half - self._a) *
            
              
                    (half 
            
            - self._b) * (half -
            
               self._c))



            
            
              def
            
            
               main():
    a, b, c 
            
            = 3, 4, 5
    
            
              #
            
            
               静态方法和类方法都是通过给类发消息来调用的
            
            
              if
            
            
               Triangle.is_valid(a, b, c):
        t 
            
            =
            
               Triangle(a, b, c)
        
            
            
              print
            
            
              (t.perimeter())
        
            
            
              #
            
            
               也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
            
            
              #
            
            
               print(Triangle.perimeter(t))
            
            
              print
            
            
              (t.area())
        
            
            
              #
            
            
               print(Triangle.area(t))
            
            
              else
            
            
              :
        
            
            
              print
            
            (
            
              '
            
            
              无法构成三角形.
            
            
              '
            
            
              )



            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    main()
            
          

4   继承和多态

刚才我们提到了,可以在已有类的基础上创建新类,这其中的一种做法就是让一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写。提供继承信息的我们称之为父类,也叫超类或基类;得到继承信息的我们称之为子类,也叫派生类或衍生类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力,在实际开发中,我们经常会用子类对象去替换掉一个父类对象,这是面向对象编程中一个常见的行为,对应的原则称之为里氏替换原则。下面我们先看一个继承的例子。

            
              class
            
            
               Person(object):
    
            
            
              def
            
            
              __init__
            
            
              (self, name, age):
        self._name 
            
            =
            
               name
        self._age 
            
            =
            
               age

    @property
    
            
            
              def
            
            
               name(self):
        
            
            
              return
            
            
               self._name

    @property
    
            
            
              def
            
            
               age(self):
        
            
            
              return
            
            
               self._age

    @age.setter
    
            
            
              def
            
            
               age(self, age):
        self._age 
            
            =
            
               age

    
            
            
              def
            
            
               study(self):
        
            
            
              print
            
            (
            
              '
            
            
              %s study  python  ing 
            
            
              '
            
            %
            
               self._name)

    
            
            
              def
            
            
               eating(self):
        
            
            
              if
            
             self._age >= 18
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s eat banana ing 
            
            
              '
            
             %
            
               self._name)
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              %s eat watermelon ing
            
            
              '
            
             %
            
               self._name)



            
            
              class
            
            
               Student(Person):
    
            
            
              def
            
            
              __init__
            
            
              (self, name, age, grade):
        super().
            
            
              __init__
            
            
              (name, age)
        self._grade 
            
            =
            
               grade

    @property
    
            
            
              def
            
            
               grade(self):
        
            
            
              return
            
            
               self._grade

    @grade.setter
    
            
            
              def
            
            
               grade(self, grade):
        self._grade 
            
            =
            
               grade

    
            
            
              def
            
            
               study(self, course):
        
            
            
              print
            
            (
            
              '
            
            
              %s的%s正在学习%s.
            
            
              '
            
             %
            
               (self._grade, self._name, course))



            
            
              class
            
            
               Teacher(Person):
            
            
              def
            
            
              __init__
            
            
              (self, name, age, title):
        super().
            
            
              __init__
            
            
              (name, age)
        self._title 
            
            =
            
               title

    @property
    
            
            
              def
            
            
               title(self):
        
            
            
              return
            
            
               self._title

    @title.setter
    
            
            
              def
            
            
               title(self, title):
        self._title 
            
            =
            
               title

    
            
            
              def
            
            
               teach(self, course):
        
            
            
              print
            
            (
            
              '
            
            
              %s%s正在讲%s.
            
            
              '
            
             %
            
               (self._name, self._title, course))



            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    stu 
            
            = Student(
            
              '
            
            
              wangdachui
            
            
              '
            
            , 15, 
            
              '
            
            
              初三
            
            
              '
            
            
              )
    stu.study(
            
            
              '
            
            
              数学
            
            
              '
            
            
              )
    stu.eating()
    t 
            
            = Teacher(
            
              '
            
            
              lancer
            
            
              '
            
            , 38, 
            
              '
            
            
              loser
            
            
              '
            
            
              )
    t.teach(
            
            
              '
            
            
              Python程序设计
            
            
              '
            
            
              )
    t.eating()
            
          

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论