• 面向对象--第二部分


    面向对象

    面向对象三大特点

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

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

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

    类的继承

    • 相关概念

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

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

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

    • 继承语法:

      # 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__)    

    练习

    • 设计一个银行系统

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

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

  • 相关阅读:
    BouncyCastle 密钥转换
    java中公钥,私钥,pkcs1格式,pkcs8格式互转
    与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence
    RSA加解密时报algid parse error, not a sequence错误
    RSA算法原理(二)
    RSA算法原理(一)
    RSA加密的java实现---亲测
    Linux SSH和SFTP服务分离
    文件夹的rwx权限
    AMD 和 CMD 的区别有哪些?
  • 原文地址:https://www.cnblogs.com/542684416-qq/p/9807126.html
Copyright © 2020-2023  润新知