• python - 类和对象


    What(是什么)

    • 类是什么?对象又是什么?
    • 首先了解下封装的概念:把乱七八糟的数据扔进列表里面,这是一种封装;把常用的代码打包成一个函数,这也是一种封装。
    • 对象就是这种封装思想的进一步,把数据和代码封装在一块。它源于真实世界。
    • 比如,乌龟是真实世界的一个对象,那么怎么来描述这个对象呢(乌龟)?分成两部分:
      • 从静态的特征:黑色的,四条腿,5kg重,有外壳等等。
      • 从动态的行为:会爬,会咬人,吃东西,睡觉等等。
    • 再举个例子:
      • 如在真实世界中的校园有学生和老师,学生有学号、姓名、班级等(属性),还有学习、吃饭、走路等行为(方法)。
      • 如果开发一个校园管理系统,那么在构建的时候,有老师和学生等“类”;也有张三、李四作为学生类里面的个体,这就是“对象”。
    • 如下图的汽车
      在这里插入图片描述
    • 这种思想,有哲学方面的考究,如柏拉图的理念论,现实世界的个体(对象)是理念(模型)的投影(类)。
    • 简单来说,类是一种高级抽象,就是一种高级的数据类型,是对象的蓝图,就是用来定义你要用的对象的属性和行为的。

    Why(为什么)

    • 为什么要用到类与对象呢?
    • 先说作用:类里面可以写实现一些功能的代码,可以减少代码的复用。
    • 这种编程思想的精髓就在:封装、继承、多态,这个我们后面会说怎么应用。
    • 类与对象是同时出现的,光有类,只有模型,没有对其实际操作的对象,是什么都干不了的。

    How(怎么用)

    • 知道了是什么,为什么,接下来就是怎么用呢?

    定义类

    • 语法:在这里插入图片描述
    • 如上面的小汽车:
      在这里插入图片描述

    创建对象

    • 类是模板,根据模板创建的实例,也就是“对象”。
    • 如图
      在这里插入图片描述

    类的成员

    • 在类体中可以包含类的成员。
      在这里插入图片描述
    • 成员变量:保存类或对象的属性。(变量)
    • 构造方法:一种特殊的函数,初始化类的成员变量。
    • 成员方法:类中定义的函数。(方法/行动)
    • 属性:对类进行封装而提供的特殊方法。
    • 实例变量/方法与类变量/方法的区别:实例变量/方法属于对象,通过对象调用;类变量/方法属于类,通过类调用。
      在这里插入图片描述

    实例变量

    • 对象个体特有的“数据”。
      在这里插入图片描述
    • 类中的self表示当前对象,构造方法中的self参数说明了这个方法属于实例,self.age表示age属于实例,即实例成员变量。

    构造方法

    • 用来创建和初始化实例变量。
    • 第1个参数是self,后面的参数用来初始化实例变量。调用构造方法就不用传入self参数了。
      在这里插入图片描述

    实例方法

    • 某个实例(对象)个体特有的方法。
    • 第一个参数self,绑定实例与方法,调用是不需要传入self。
      在这里插入图片描述

    类变量

    • 属于类的变量,不属于单个对象。
    • 如,一个银行账户的类,三个变量:账户金额、利率、账户名。利率是相同的,账户金额跟账户名是不同的。 所以利率是类变量(所有实例成员共享的),其余两个是实例变量。
      在这里插入图片描述

    类方法

    • 属于类,不属于个体对象。
    • 第1个参数不是self,而是类本身。
      在这里插入图片描述
    • 注意:类方法不能访问实例方法和实例变量。

    封装性

    • 面向对象的基本特性之一。
    • 封装隐藏对象内部细节,保留有限的对外接口,使操作对象格外简单。

    私有变量

    • 内部数据(成员变量)会被封装为“私有变量”,外部调用者只能通过方法调用。
    • python默认变量是公有的,前面加__(双下划线),即变成私有变量。
      在这里插入图片描述

    私有方法

    • 同理,在定义方法时加上__(双下划线),即变成私有方法。
      在这里插入图片描述

    使用属性

    • 为了实现对象的封装,一个类中,不该有公有的成员变量,这些成员变量都应该设为私有的,然后通过公有的set和get方法访问。

      class Dog():
          def __init__(self, name, age, sex="雄性"):
              self.name = name
              self.__age = age
              self.sex = sex
      
          def run(self):
              print("{}在跑...".format(self.name))
      
          # 定义get()方法,返回私有实例变量__age
          def get_age(self):
              return self.__age
      
          # 定义set()方法,通过age参数更新私有实例变量__age
          def set_age(self, age):
              self.__age = age
      
      d = Dog("球球",3)
      print("我们家狗{}岁了".format(d.get_age()))
      d.set_age(4)
      print("我们家狗{}岁了".format(d.get_age()))
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    • 返回结果
      在这里插入图片描述

    • 以上,是定义了两个公有方法,访问被封装的私有成员变量的。另外一种方法如下

      class Dog():
          def __init__(self, name, age, sex="雄性"):
              self.name = name
              self.__age = age
              self.sex = sex
      
          def run(self):
              print("{}在跑...".format(self.name))
      
          # # 定义get()方法,返回私有实例变量__age
      
      
          # def get_age(self):
          #     return self.__age
      
          @property
          def age(self):
              return self.__age
      
          # # 定义set()方法,通过age参数更新私有实例变量__age
          # def set_age(self, age):
          #     self.__age = age
      
          @age.setter
          def age(self, age):
              self.__age = age
      
      d = Dog("球球",3)
      print("我们家狗{}岁了".format(d.age))
      d.age = 4
      print("我们家狗{}岁了".format(d.age))
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
    • 运行结果
      在这里插入图片描述

    • 本质上就是,在方法前面加上装饰器,使其成为属性,用起来类似公有变量。

    继承性

    继承

    • 面向对象的特征之一。
    • 在现实世界里,继承关系无处不在。如猫和动物之间关系:猫是一种特殊动物,具有动物的全部特性与行为,即数据和操作。这种关系中,动物是一般类,称为“父类”,猫是特殊类,称为“子类”。
    • 特殊类拥有一般类的全部数据与操作,可以称为子类继承父类。
    • 在python中声明子类继承父类,只需要在定义类时,在类的后面使用一对小括号指定父类即可。
      class Animal:
          def __init__(self, name):
              self.name = name
      
          def show_info(self):
              return "动物名字:{0}".format(self.name)
      
          def move(self):
              print("移动ing")
      
      # 子类定义
      class Cat(Animal):
          def __init__(self, name, age):
          	# 使用super()方法调用父类构造方法,初始化父类成员变量
              super().__init__(name)
              self.age = age
      
      cat = Cat("tom",4)
      cat.move()
      print(cat.show_info())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 显示结果
      在这里插入图片描述
    • 子类继承父类,只有那些公有的成员变量和方法,才可以继承。
    • 子类调用父类构造方法,流程如下图:
      在这里插入图片描述

    多继承

    • python支持一个子类继承多个父类,如果子类继承多个父类,父类中有相同的成员变量或方法,则子类优先继承左边(这个左边指的是类定义时括号中,父类参数的位置),从左到右,级别从高到低。
      class Horse:
          def __init__(self, name):
              self.name = name
      
          def show_info(self):
              return "马的名字:{0}".format(self.name)
      
          def move(self):
              print("马在跑...")
      
      class Donkey:
          def __init__(self, name):
              self.name = name
      
          def show_info(self):
              return "驴的名字:{0}".format(self.name)
      
          def move(self):
              print("驴在跑...")
      
          def roll(self):
              print("驴在滚...")
      
      class Mule(Horse, Donkey):
          def __init__(self, name, age):
              super().__init__(name)
              self.age = age
      
      m = Mule("tom",10)
      # 继承马的run(继承时马在左边)
      m.move()
      # 继承驴的roll
      m.roll()
      # 同理,继承马的show_info
      print(m.show_info())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
    • 运行结果
      在这里插入图片描述

    方法重写

    • 如果子类的方法名与父类的方法名相同,子类的方法会重写父类的同名方法(也可以认为是覆盖)。
      class Horse:
          def __init__(self, name):
              self.name = name
      
          def show_info(self):
              return "马的名字:{0}".format(self.name)
      
          def move(self):
              print("马在跑...")
      
      class Donkey:
          def __init__(self, name):
              self.name = name
      
          def show_info(self):
              return "驴的名字:{0}".format(self.name)
      
          def move(self):
              print("驴在跑...")
      
          def roll(self):
              print("驴在滚...")
      
      class Mule(Horse, Donkey):
          def __init__(self, name, age):
              super().__init__(name)
              self.age = age
          def show_info(self):
              return "骡的名字是:{0},{1}岁".format(self.name, self.age)
      
      m = Mule("tom",10)
      # 继承马的run(继承时马在左边)
      m.move()
      # 继承驴的roll
      m.roll()
      # 子类自身定义的方法
      print(m.show_info())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
    • 运行结果
      在这里插入图片描述

    多态性

    • 面向对象的基本特征之一。
    • 多态指的是:对象可以表现出多种形态。如,猫,鸭,狗都属于动物,都有“叫”和“动”等行为,但是叫的方式不同,动的方式也不同。

    继承与多态

    • 在多个子类继承父类,并重写父类方法后,这些子类所创建的对象之间就是多态的。
      class Animal:
          def speak(self):
              print("叫起来,啥玩意叫?")
      
      class Dog(Animal):
          def speak(self):
              print("小狗,旺。。。")
      
      class Cat(Animal):
          def speak(self):
              print("小猫咪,喵。。。")
      
      ca = Cat()
      do = Dog()
      ca.speak()
      do.speak()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 运行结果
      在这里插入图片描述

    鸭子类型测试

    • 鸭子类型测试:若看到一只鸟走路像鸭子,游泳像鸭子,叫起来也像鸭子,那么这只鸟可以被称为鸭子。
    • python解释器不检查发生多态的对象是否继承了一个父类,只要它们有相同的行为(方法),它们之间就是多态的。
    • 如,我们可以定义一个函数,专门用来做相同行为处理。
      # 定义函数,接收所有的speak()方法对象
      def start(obj):
          obj.speak()
      
      class Animal:
          def speak(self):
              print("叫起来,啥玩意叫?")
      
      class Dog(Animal):
          def speak(self):
              print("小狗,今年旺不旺,旺。。。")
      
      class Cat(Animal):
          def speak(self):
              print("小猫咪,别骂人呀,喵。。。")
      
      def strat(obj):
          obj.speak()
      
      start(Dog())
      start(Cat())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    • 运行结果
      在这里插入图片描述
  • 相关阅读:
    四十一、《大数据项目实战之用户行为分析》使用ECharts进行前端视图展示
    Excel常用函数
    Windows 上下载并提取 Wikipedia
    燃气管网监测系统,让城市生命线更安全
    小文智能GPT助手介绍
    eBPF会成为服务网格的未来吗?
    计算机网络第6章应用层 单元测试(习题+答案+图文解析)
    SwiftUI 4.0(iOS 16+)使用新的 Gauge 视图极简实现仪表盘外观
    python面试题总结(二)
    decltype 类型指示符
  • 原文地址:https://blog.csdn.net/Cherish1ove/article/details/125832536