[python]-面向对象高级

类的定义

方式1

在之前的学习过程中,我们都使用了这种定义类的语法(旧式类):

方式2

在编写类时,也可以写成如下格式(旧式类):

方式3

此外,还有一种更为常见的定义类的语法(新式类),如下:

object是所有类的父类,Python中所有的类都直接或者间接继承自object类.

继承

什么是继承

  1. 继承: 一个类从另一个已有的类获得其成员的相关特性,就叫作继承!(站在子类角度)
  2. 派生: 从一个已有的类产生一个新的类,称为派生! (站在父类角度)
  3. 很显然,继承和派生其实就是从不同的方向来描述的相同的概念而己,本质上是一样的!
  4. 父类: 也叫作基类,就是指已有被继承的类!
  5. 子类: 也叫作派生类或扩展类

单继承

单继承就是一个子类只能继承自一个父类,不能继承多个类。这个子类会有具有父类的属性和方法。

多继承

多继承就是一个类同时继承了多个父类,并且同时具有所有父类的属性和方法。

  1. 例如: 孩子会继承父亲和母亲的方法和属性
  1. 继承的优先级: 从左往右,就近原则.
  2. MRO(Method Resolution Order): 方法解析顺序
  • 当一个类有多个父类时,默认使用第一个父类的同名属性和方法,
  • 可以使用 类名.mro 属性 或 类名.mro() 方法查看调用的先后顺序。

方法重写和属性重写

重写也叫作覆盖,就是当子类属性或方法与父类的属性或方法名字相同时,从父类继承下来的成员可以重新定义! 子类重写父类的属性和方法,优先会调用子类的属性和方法

调用层次: 遵循就近原则,子类有就用,没有就去父类找,依次查找其所有的父类,有就用,没有就报错.

子类调用父类方法

子类中仍想要保留父类的行为,则需要在子类中调用父类方法. 可以直接使用父类名来进行调用

语法: 父类名.父类函数名(self)

特点: 精准访问, 想找哪个父类, 就调用哪个父类

使用super()调用父类方法

语法: super().父类函数名(self)

注意: 使用super()可以自动查找父类,有就用, 没有就报错 (从左往右逐层查找)

建议: 适合单继承使用,多继承不建议使用

多层继承

object <- Master,School <- Prentice <- Tusun

封装

什么是封装?

在软件编程中,将属性和方法书写到类的里面的操作即为封装,封装可以为属性和方法添加私有权限。

私有属性和私有方法

在Python中,可以为属性和方法设置私有权限,即设置某个属性或方法不继承给子类。

设置私有属性和方法的方式:在属性或方法名前面加上 __ (双下划线),格式:

私有属性和方法使用规则:

  • 只能在类的内部使用,不能在类的外部使用;
  • 如果想在类的外部使用通过公共接口

定义和获取私有属性

私有属性不能直接访问,在Python中,一般定义方法名'get_xx'用来获取私有属性,定义'set_xx'用来修改私有属性值。

定义和获取私有方法

访问私有方法,可以使用重新设置一个公有方法来访问。

多态

多态,指的是多种状态。比如: 同样一个函数在不同的场景下有不同的状态

同样的行为(函数),传入不同的对象,得到不同的状态

多态成立的条件

实现多态的三个条件:

1、有继承 (定义父类、定义子类,子类继承父类)

2、函数重写(子类重写父类的函数)

3、父类引用指向子类对象 (子类对象传给父类对象调用者)

复制代码
"""
演示多态
"""
# 1.有继承
class Animal:  # 抽象类: 定义了抽象方法的类
    def speak(self):  # 抽象方法: 没有方法体的方法
        pass


# 2.有函数重写
class Dog(Animal):
    def speak(self):
        print("狗叫: 汪汪汪")


class Cat(Animal):
    def speak(self):
        print("猫叫: 喵喵喵")


 # 3.父类引用指向子类对象 (多态函数)
def make_noise(an: Animal):  # 限制an类型
    # an:Animal = Dog()
    an.speak()


if __name__ == '__main__':
    d = Dog()
    make_noise(d)  # 狗叫: 汪汪汪

    c = Cat()
    make_noise(c)  # 猫叫: 喵喵喵

多态案例

构建对象对战平台object_play

  1. 英雄一代战机(战斗力60)与敌军战机(战斗力70)对抗。英雄1代战机失败!
  2. 卧薪尝胆,英雄二代战机(战斗力80)出场!,战胜敌军战机!
  3. 对象对战平台object_play,代码不发生变化的情况下,完成多次战斗

思路分析:

  • 抽象战机类 HeroFighter AdvHeroFighter; 敌机 EnemyFighter;
  • 构建对象战斗平台,使用多态实现

代码实现:

复制代码
# 1.定义英雄机1代
class HeroFighter(object):
    def power(self):
        return 60

# 2.定义英雄机2代
class AdvHeroFighter(HeroFighter):
    def power(self):
        return 80

# 3.定义敌机1代
class EnemyFighter(object):
    def power(self):
        return 70

# 4.构建对战函数 (多态方法)
def object_play(hero, enemy):
    # 参1: 英雄机, 参数2: 敌机
    # 看面向对象代码,要时刻注意什么时候发生多态
    if hero.power() > enemy.power():
        print("英雄机战胜敌机!")
    else:
        print("敌机战胜英雄机!")

if __name__ == '__main__':
    h1 = HeroFighter()
    h2 = AdvHeroFighter()
    e1 = EnemyFighter()

    # 一代战机出战
    object_play(h1, e1)
    # 二代战机出战
    object_play(h2, e1)

多态的好处:

1、通过多态语法轻松的实现模块和模块之间的解耦合; 实现了软件系统的可扩展;

2、对解耦合解释:

  • 搭建的平台函数相当于任务的调用者;
  • 子类、孙子类重写父类的函数,相当于子任务;
  • 相当于任务的调用者和任务的编写者进行了解耦合;

3、对可扩展的解释:

  • 同一个多态方法, 传入不同的对象, 就会有不同的结果

为了更好的使用多态这个特性,行业专家们又提出来抽象类,抽象接口的概念

  1. 抽象类就好比定义一个标准,包含了一些抽象的方法,要求子类必须实现。
  1. 抽象类的概念(也可以称之为接口)
  • 抽象类: 含有抽象方法的类称之为抽象类
  • 抽象方法: 方法体是空实现的(pass)称之为抽象方法
  1. 这种设计的含义是:
  • ·父类用来确定有哪些方法 (父类制定接口标准)·
  • 具体的方法实现有子类来实现 (子类实现接口标准)

其他特性

对象属性

类属性

类方法

静态方法

如果函数中要用 类对象,就定义成类方法,否则定义成静态方法,除此外,并无任何区别.

案例

需求分析

  1. 基本需求
  • a.可以显示基本的版本信息和操作界面;
  • b.可以通过键盘输入信息来完成基本功能,例如选择序号、确认退出、添加学生、修改信息等
  • c.学生属性信息有姓名、性别、年龄、联系方式、描述信息等;
  • d.使用系统可对学生信息进行添加、修改、删除、查询等操作;
  • e.可以使用文件对学生信息进行加载、保存等;
  • f.可重复对学生进行增删查改操作,当确认退出系统后,则直接退出系统;
  • g.请使用面向对象的编程思想完成项目。
  1. 角色分析

开发实现

  1. 设计学生类

    """
    学生类
    """
    class Student:
    def init(self, name, gender, age, phone, desc):
    """
    初始化属性信息
    :param name: 学生姓名
    :param gender: 性别
    :param age: 年龄
    :param phone: 手机号
    :param desc: 描述
    """
    self.name = name
    self.gender = gender
    self.age = age
    self.phone = phone
    self.desc = desc

    复制代码
     def __str__(self):
         return f'姓名: {self.name} 年龄: {self.age} 性别: {self.gender} 手机号: {self.phone} 描述: {self.desc}'

    if name == 'main':
    s1 = Student("张三", "男", 18, "12345678901", "描述")
    print(s1)

  2. 设计系统框架

    """
    系统管理类
    """
    class Cms(object):
    def init(self):
    self.stu_list = []

    复制代码
     def show_emnu(self):
         print("*" * 23)
         print("学生管理系统")
         print("\t1.添加学生信息")
         print("\t2.删除学生信息")
         print("\t3.修改学生信息")
         print("\t4.查询某个学员")
         print("\t5.查询全部学员")
         print("\t6.保存信息")
         print("\t0.退出系统")
         print("*" * 23)
    
     def add_stu(self):
         pass
    
     def del_stu(self):
         pass
    
     def update_stu(self):
         pass
    
     def query_stu(self):
         pass
    
     def query_all_stu(self):
         pass
    
     def save_stu(self):
         pass
    
     def start(self):
         while True:
             self.show_emnu()
             input_num = input("请输入操作编号:")
             if input_num == "1":
                 print("添加学生信息")
                 self.add_stu()
             elif input_num == "2":
                 print("删除学生信息")
                 self.del_stu()
             elif input_num == "3":
                 print("修改学生信息")
                 self.update_stu()
             elif input_num == "4":
                 print("查询学生信息")
                 self.query_stu()
             elif input_num == "5":
                 print("查询全部学生信息")
                 self.query_all_stu()
             elif input_num == "6":
                 print("保存学生信息")
                 self.save_stu()
             elif input_num == "0":
                 result = input("确认要退出吗? (Y?N)")
                 if result.lower() == "y":
                     print("感谢使用, 期待下次再会!")
                     break
             else:
                 print("输入错误,请重新输入:")

    if name == 'main':
    cms = Cms()
    cms.start()

  3. 完成入口文件

    """
    入口文件
    """
    from cms import Cms

    if name == 'main':
    cms = Cms()
    cms.start()

  1. 实现学生的增删改查

    """
    系统管理类
    """
    from student import Student

    class Cms(object):
    def init(self):
    self.stu_list = [
    Student("张三", "男", 18, "12345678901", "描述"),
    Student("李四", "女", 19, "12345678902", "描述"),
    Student("王五", "男", 20, "12345678903", "描述"),
    Student("赵六", "女", 21, "12345678904", "描述"),
    Student("孙七", "男", 22, "12345678905", "描述"),
    ]

    复制代码
     def show_emnu(self):
         print("*" * 23)
         print("学生管理系统")
         print("\t1.添加学生信息")
         print("\t2.删除学生信息")
         print("\t3.修改学生信息")
         print("\t4.查询某个学员")
         print("\t5.查询全部学员")
         print("\t6.保存信息")
         print("\t0.退出系统")
         print("*" * 23)
    
     def add_stu(self):
         name = input("输入学生姓名:")
         gender = input("输入学生性别:")
         age = int(input("输入学生年龄:"))
         phone = input("输入学生电话:")
         desc = input("输入学生描述信息:")
         stu = Student(name, gender, age, phone, desc)
         self.stu_list.append(stu)
         print(f"添加学生 {name} 成功")
    
     def del_stu(self):
         name = input("输入要删除学生的姓名:")
         for stu in self.stu_list:
             if stu.name == name:
                 self.stu_list.remove(stu)
                 print(f"删除学生 {name} 成功")
                 break
             else:
                 print(f"没有找到学生 {name}")
    
     def update_stu(self):
         name = input("输入要修改学生的姓名:")
         for stu in self.stu_list:
             if stu.name == name:
                 stu.name = input("输入学生姓名:")
                 stu.gender = input("输入学生性别:")
                 stu.age = int(input("输入学生年龄:"))
                 stu.phone = input("输入学生电话:")
                 stu.desc = input("输入学生描述信息:")
                 print(f"修改学生 {name} 成功")
                 break
             else:
                 print(f"没有找到学生 {name}")
    
     def query_stu(self):
         name = input("输入要查询学生的姓名:")
         for stu in self.stu_list:
             if stu.name == name:
                 print(stu)
                 break
             else:
                 print(f"没有找到学生 {name}")
    
     def query_all_stu(self):
         if len(self.stu_list) == 0:
             print("暂无学生信息!")
             return
         else:
             for stu in self.stu_list:
                 print(stu)
             print("")
    
     def save_stu(self):
         pass
    
     def start(self):
         while True:
             self.show_emnu()
             input_num = input("请输入操作编号:")
             if input_num == "1":
                 self.add_stu()
             elif input_num == "2":
                 self.del_stu()
             elif input_num == "3":
                 self.update_stu()
             elif input_num == "4":
                 self.query_stu()
             elif input_num == "5":
                 self.query_all_stu()
             elif input_num == "6":
                 self.save_stu()
             elif input_num == "0":
                 result = input("确认要退出吗? (Y?N)")
                 if result.lower() == "y":
                     print("感谢使用, 期待下次再会!")
                     break
             else:
                 print("输入错误,请重新输入:")

    if name == 'main':
    cms = Cms()
    cms.start()

  2. 保存学生信息到文件

  • 扩展 dict 方法
  • 完整的功能实现

    """
    系统管理类
    """
    import time

    from student import Student

    class Cms(object):
    def init(self):
    self.stu_list = []

    复制代码
      @staticmethod
      def show_emnu():
          print("*" * 23)
          print("学生管理系统")
          print("\t1.添加学生信息")
          print("\t2.删除学生信息")
          print("\t3.修改学生信息")
          print("\t4.查询某个学员")
          print("\t5.查询全部学员")
          print("\t6.保存信息")
          print("\t0.退出系统")
          print("*" * 23)
    
      def add_stu(self):
          name = input("输入学生姓名:")
          gender = input("输入学生性别:")
          age = int(input("输入学生年龄:"))
          phone = input("输入学生电话:")
          desc = input("输入学生描述信息:")
          stu = Student(name, gender, age, phone, desc)
          self.stu_list.append(stu)
          print(f"添加学生 {name} 成功")
    
      def del_stu(self):
          name = input("输入要删除学生的姓名:")
          for stu in self.stu_list:
              if stu.name == name:
                  self.stu_list.remove(stu)
                  print(f"删除学生 {name} 成功")
                  break
              else:
                  print(f"没有找到学生 {name}")
    
      def update_stu(self):
          name = input("输入要修改学生的姓名:")
          for stu in self.stu_list:
              if stu.name == name:
                  stu.name = input("输入学生姓名:")
                  stu.gender = input("输入学生性别:")
                  stu.age = int(input("输入学生年龄:"))
                  stu.phone = input("输入学生电话:")
                  stu.desc = input("输入学生描述信息:")
                  print(f"修改学生 {name} 成功")
                  break
              else:
                  print(f"没有找到学生 {name}")
    
      def query_stu(self):
          name = input("输入要查询学生的姓名:")
          for stu in self.stu_list:
              if stu.name == name:
                  print(stu)
                  break
              else:
                  print(f"没有找到学生 {name}")
    
      def query_all_stu(self):
          if len(self.stu_list) == 0:
              print("暂无学生信息!")
              return
          else:
              for stu in self.stu_list:
                  print(stu)
              print("")
    
      def save_stu(self):
          with open("/stu_data.txt", "w", encoding="utf-8") as dest_f:
              # 把[学生对象, ...] 转成 [学生对象字典, ...]
              stu_dict = [stu.__dict__ for stu in self.stu_list]
              # 把字典列表持久化
              dest_f.write(str(stu_dict))
    
      def out(self):
          result = input("确认要退出吗? (Y?N)")
          if result.lower() == "y":
              self.save_stu()
              print("感谢使用, 期待下次再会!")
              return True
          else:
              return False
    
      def load_stu(self):
          try:
              with open("/stu_data.txt", "r", encoding="utf-8") as src_f:
                  stu_data = src_f.read()
                  # 把字符串转换成字典列表
                  stu_list = eval(stu_data)
                  # 如果列表是空重新赋值
                  if len(stu_list) == 0:
                      stu_list = []
                  # 把字典列表转换成学生对象列表
                  self.stu_list = [Student(**stu) for stu in stu_list]
          except:
              with open("/stu_data.txt", "w", encoding="utf-8") as dest_f:
                  pass
    
      def start(self):
          self.load_stu()
    
          while True:
              time.sleep(1)
              self.show_emnu()
              input_num = input("请输入操作编号:")
              if input_num == "1":
                  self.add_stu()
              elif input_num == "2":
                  self.del_stu()
              elif input_num == "3":
                  self.update_stu()
              elif input_num == "4":
                  self.query_stu()
              elif input_num == "5":
                  self.query_all_stu()
              elif input_num == "6":
                  self.save_stu()
                  print("学生信息保存成功!")
              elif input_num == "0":
                  res = self.out()
                  if res:
                      break
              else:
                  print("输入错误,请重新输入:")

    if name == 'main':
    cms = Cms()
    cms.start()

相关推荐
向量引擎小橙1 小时前
从“对话助手”到“数字架构师”:Claude 4.6 Opus 如何凭一己之力,终结全球程序员的“CRUD 焦虑”?
人工智能·python·gpt·深度学习
小鸡吃米…2 小时前
TensorFlow - 单层感知机
人工智能·python·tensorflow
康小庄2 小时前
Java读写锁降级
java·开发语言·spring boot·python·spring·java-ee
咩图2 小时前
VSCode+Python创建项目
开发语言·python
zhanglu51162 小时前
Java Lambda 表达式使用深度解析
开发语言·前端·python
Hello.Reader2 小时前
Flink Python REPL(pyflink-shell)实战:本地/远程/YARN 三种启动方式 + Table API 交互开发流程
python·flink·交互
henry1010102 小时前
利用Python一键创建AWS EC2实例
linux·python·云计算·aws·ec2
EveryPossible2 小时前
工作流练习
服务器·python·缓存
一次旅行2 小时前
接口自动化测试模板
数据库·python·pytest