面向对象--第二部分

面向对象

面向对象三大特点

  • 封装:既是对数据结构的封装,有是处理数据的方法的封装。

  • 继承:强调的父子类的关系。

  • 多态:不同对象调用相同的方法,有不同的响应。

类的继承

  • 相关概念

    • 继承:父类的方法和属性,子类直接拥有,称为继承。

    • 派生:子类在父类的基础上衍生出新的特征(属性和行为)。

    • 总结:其实他们是一回事,只是描述问题的角度不同(继承强调相同点,派生强调不同点)

  • 继承语法:

    # class Animal:
    # 当没有写父类时,默认继承自object
    class Animal(object):
        def __init__(self, name):
            self.name = name
    ​
        def run(self):
            print('小动物喜欢一天到晚跑个不停')
            
    # 继承自另一个类 
    class Dog(Animal):
        pass
    ​
    d = Dog('旺财')
    # 直接拥有父类的属性
    print(d.name)
    # 也拥有父类的行为
    d.run()
  • 派生示例

    class Animal:
        def run(self):
            print('一天到晚不停的跑')
                
    class Cat(Animal):
        def eat(self):
            print('猫喜欢吃鱼')
    ​
    c = Cat()
    ​
    # 继承的方法
    c.run()
    # 衍生的发生
    c.eat()
    # 动态添加属性
    c.color = '白色'
    print(c.color)       
  • 方法重写

    • 父类的方法完全不合适,可以覆盖重写

    • 父类的不是完全合适,可以添加完善

    • 示例

      class Animal:
          def eat(self):
              print('小动物一天到晚吃个不停')
      ​
          def run(self):
              print('小动物一天到晚跑个不停')
      ​
      class Cat(Animal):
          # 完全不合适,覆盖重写
          def run(self):
              print('俺走的是猫步')
      ​
          # 父类的方法不够完善,需要添加完善
          def eat(self):
              # 保留父类方法中的内容
              # Animal.eat(self)  # 不建议使用
              # super(Cat, self).eat()
              # 简化方案,推荐使用
              super().eat()
              print('俺喜欢吃鱼')
              
      c = Cat()
      c.run()
      c.eat()
  • 多继承:一个类可以有多个父类

    class A:
        def eat(self):
            print('eat func in class A')
                
    class B:
        def eat(self):
            print('eat func in class B')
    ​
        def test(self):
            print('test func in class B')
            
    class C(A, B):
        def eat(self):
            # 不重写方法,或者使用super,都是按照书写的先后顺序
            # 默认会使用前面的类的方法
            # super().eat()
            # 明确指定调用哪个父类的方法
            B.eat(self)
    ​
    c = C()
    ​
    c.eat()
    c.test()
  • 访问权限

    • 权限

      • 公有的:类中的普通的属性和方法,默认都是公有的;可以在类外、类内以及子类中使用。

      • 私有的:定义时在前面添加两个下划线即可,只能在本类中使用,类外及子类中不能使用

    • 示例

       class Person:
              def __init__(self, name):
                  self.name = name
                  self.__age = 20def test(self):
                  # 可以在类的内部使用
                  print(self.__age)
      ​
              def __hello(self):
                  print('hello world!')
                  
          class Man(Person):
              def introduce(self):
                  # 私有属性不能在子类中使用
                  print('我叫{},今年{}岁'.format(self.name, self.__age))
      ​
          p = Person('小明')
          # print(p.name)
          # 当属性前添加两个下划线后,无法在外部访问
          # print(p.age)
          # print(p.__age)
          # print(p.__dict__)
          # 默认加两个下划线的属性名前面添加了'_类名'
          # 不建议访问
          # print(p._Person__age)
          # p.test()
      # p.__hello()
      ​
          m = Man('ergou')
          # m.introduce()
          print(m.__dict__)
  • 类属性

    • 说明:定义在类中,但是在方法外的属性,通常会放在类的开头,这样的属性称为类属性

    • 示例:

       class Person:
            # 类属性
            # nation = '中国'
      # 限制对象可以使用的属性,可以提高访问的效率
            __slots__ = ('name', 'age', 'nation')
      ​
            def __init__(self, name):
                self.name = name
                self.nation = 'china'
              
      # 通过类名访问类属性
      print(Person.nation)
      p = Person('小明')
      print(p.name)
      # 通过对象也可以访问类属性,但是不建议
      print(p.nation)
      ​
      # 特殊的类属性
      # 类名字符串
      print(Person.__name__)
      ​
      # 基类组成的元组
      print(Person.__bases__)
      ​
      # 类相关的信息
      print(Person.__dict__)
      ​
      print(Person.__slots__)
      ​
      p.age = 20
      # p.xxx = 'yyy'    
  • 类方法

    • 说明:

      • 通过类名调用的方法

      • 定义时通过装饰器classmethod进行装饰的方法

    • 作用:

      • 可以创建对象或简洁的创建对象

      • 可以对外提供简洁易用的接口

    • 示例1:创建对象

      class Person:
              def eat(self):
                  print('我喜欢吃麻辣烫,不要麻椒和辣椒')
      ​
              # 定义类方法
              @classmethod
              def test(cls):
                  # cls:表示当前类
                  print(cls, '类方法')
      ​
              @classmethod
              def create(cls):
                  p = cls()
                  p.age = 1
                  return p
              
          xiaoming = Person()
          xiaoming.eat()
      ​
          # 类方法通过类名调用
          Person.test()
      ​
          # 创建或简洁的创建对象
          xiaohua = Person.create()
          print(xiaohua.age)
  • 示例2:对外提供简单易用的接口

    class Number:
        def __init__(self, num1, num2):
            self.num1 = num1
            self.num2 = num2
    ​
        def add(self):
            return self.num1 + self.num2
    ​
        def sub(self):
            return self.num1 - self.num2
    ​
        def mul(self):
            return self.num1 * self.num2
    ​
        def div(self):
            if self.num2 == 0:
                return None
            return self.num1 / self.num2
    ​
        @classmethod
        def pingfanghe(cls, num1, num2):
            n1 = cls(num1, num1)
            n12 = n1.mul()
    ​
            n2 = cls(num2, num2)
            n22 = n2.mul()
    ​
            n3 = cls(n12, n22)
            return n3.add()
        
    ret = Number.pingfanghe(3, 4)
    print(ret)
  • 静态方法

    • 说明:

      • 定义时通过装饰器staticmethod装饰的方法

      • 也是通过类名进行调用

    • 示例

      class Person:
          @staticmethod
          def test():
              print('static method test')
      ​
          # 也可以创建对象
          @staticmethod
          def create():
              p = Person()
              p.age = 20
              return p
          
      Person.test()
      p = Person.create()
      print(type(p))
  • 总结:

    • 凡是静态方法能够完成的功能都可使用类方法进行完成

    • 若方法中没有使用到类名(cls),都可以使用静态方法

  • 多态特性

    • 定义:不同的对象,调用调用相同的方法,有不同的响应。

    • 示例:

      class Animal:
          def run(self):
              print('小动物走道都不一样')
      ​
      class Dog(Animal):
          def run(self):
              print('狗通常走S型')
      ​
      class Cat(Animal):
          def run(self):
              print('猫一般走猫步')
      ​
      def func(obj):
          obj.run()
      ​
      func(Cat())
      func(Dog())
  • 属性函数

    • 说明:将成员方法当做属性一样进行访问。

    • 作用:保护特定属性,或者对属性进行特定的处理。

    • 示例:

      class User:
          def __init__(self, username, password):
              self.username = username
              self.__password = password
      ​
          # 可以保护指定的属性
          @property
          def password(self):
              print('有人想偷看密码')
              return '想看密码,没门'# 设置属性时,自动调用
          @password.setter
          def password(self, password):
              print('加密存储密码')
              self.__password = '加密' + password + '加密'
              
      u = User('xiaoming', '123456')
      print(u.username, u.password)
      ​
      u.password = 'abcd'
      print(u.__dict__)    

练习

  • 设计一个银行系统

    • 类:银行卡类、用户类、操作类

    • 说明:每个类的属性和方法自行添加

原文地址:https://www.cnblogs.com/542684416-qq/p/9807126.html