Python18 面向对象编程

痴心易碎 提交于 2019-11-29 02:25:22

面向对象

  • 面向对象编程:Object Oriented Programming
    • 简称:OOP- 把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
    • 理解:面向对象中,是类与实例的关系,放在现实中人(包括了男人,女人)它是一个类,小军是人这类的具体某一个人,被叫为实例
    • 百度理解:https://baike.baidu.com/item/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/2262089?fr=aladdin
      - - - - - - - -
  • 类和实例:
    • 类:是抽象出的模版,如人
    • 定义方法:class 类名(object):object是继承的类,每个类默认都继承object
    • 代码:
      # 创建类 class People(object): pass
    • 实例:根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
    • 使用方法:实例名 = 类()
    • 代码:
      # 实例化类 man = People()
    • __init__:初始化类模版,使在初始化时候就能得到属性的值
    • 代码:
      class Student(object): def __init__(self,name,age): # self 这个值不用传 self.name = name # 属性 self.age = age bart = Student('小军','15') # 调用实例属性 print(bart.name,bart.age)
    • self:注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
    • 方法:类中的函数,与普通函数不同的点在于第一个参数永远是self
    • 代码:
      class Animal(object): # 属性(变量) name = 'xx' # 方法 def run(self): return self.name + '会跑' monkey = Animal() print(monkey.run())
      - - - - - - -
  • 数据封装:在类方法中定义一个访问类属性的方法,属性都是在类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节。
    • 代码:

      class School(object):
          def __init__(self,name,addr)
              self.name = name
              self.addr = addr
      
          # 定义一个方法 直接拿到属性
          def getProperty(self):
              return self.name,self.addr
      
          # 实例类
          school = School('mslg','America')
          sName,sAddr = school.getProperty()
          print(sName,sAddr)

  • 访问限制:如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
    • 代码:
      class Man(object): def __init__(self,name,age): self.__name = name self.__age = age def printNameAge(self): print(self.__name,self.__age) m = Man('a','12') print(m.__name) # 无法访问
    • 外部无法访问私有变量:可以创建set方法设置私有变量的值,get方法返回私有变量的值
    • 代码:
      ```
      class Student(object):
      def init(self, name, gender):
      self.name = name
      self.__gender = gender # 私有属性
      def set_gender(self,gender): # 设置私有属性的值,并进行参数校验
      if gender in ['male','female']:
      self.__gender = gender
      else:
      raise ValueError('gender is male or female')
      def get_gender(self): # 得到私有属性值的方法
      return self.__gender

      # 测试:
      bart = Student('Bart', 'male')
      if bart.get_gender() != 'male':
      print('测试失败!')
      else:
      bart.set_gender('female')
      if bart.get_gender() != 'female':
      print('测试失败!')
      else:
      print('测试成功!')
      ```
      - - - - - -
  • 继承和多态:在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
    • 代码:
      # 定义一个Dog类继承Animal类 class Dog(Animal): pass # 继承之后就拥有了父类非私有方法和属性 d = Dog() print(d.run()) # 调用父类的run方法
    • 对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类
    • 如果父类和之类拥有同一个方法(方法名,参数个数一致)调用的则是子类的方法
    • 代码:
      # 定义一个Cat类继承Animal类 class Cat(Animal): name = 'dog' def run(self): return self.name + '会跑' c = Cat() c.run # 调用的是Cat的run方法 print(c.run())
    • 多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思:
    • 代码:
      ```
      # class 也是数据类型
      isinstance(c,Animal)
      isinstance(c,Cat)
      print(isinstance(c,Animal),isinstance(c,Cat)) # Cat的实例是Cat数据类型,也是Animal数据类型
      isinstance(monkey,Dog)
      print(isinstance(monkey,Cat)) # Animal的实例不是Cat数据类型

      # 定义一个方法传入Animal类型
      def do_run(Animal):
      print(Animal.run())

      class Monkey(Animal):
      name = 'monkey'
      def run(self):
      return self.name + '会跑'
      # 调用
      do_run(Cat())
      do_run(Monkey())
      do_run(Dog())
      do_run(d)
      ```
      - - - -
  • 获取对象信息:
    • types:判断一个对象是否是函数
    • 实例:
      # types import types def fn(): pass type(fn) == types.FunctionType # 返回True
    • dir():如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
    • 代码:
      ```
      print(dir('123'))
      print(dir(Anmial()))

      ```
    • getattr()、setattr()以及hasattr():
    • 代码:
      ```
      # getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:

      class Demo(object):
      name = 'xxx123'
      age = 12
      def eat(self):
      print("eat!!!")
      demo = Demo()

      # hasattr(对象,属性) 检查对象是否有属性,返回布尔值
      hasattr(demo,'name') # 有属性 name嘛? True

      # setattr(对象,属性名,值) 设置一个属性
      setattr(demo,'addr','beijin')

      print(demo.addr) # 获取属性

      # getattr(对象,属性) 获取属性的值
      getattr(demo,'addr')

      print( hasattr(demo,'name') )
      print( getattr(demo,'addr') )
      ```

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!