全网最适合入门的面向对象编程教程:10 类和对象的Python实现-类的继承和里氏替换原则,Python模拟主机和传感器自定义类

全网最适合入门的面向对象编程教程:10 类和对象的 Python 实现-类的继承和里氏替换原则,Python 模拟主机和传感器自定义类

摘要:

本文主要介绍了类的继承的基本概念和里氏替换原则,以模拟传感器数据串口输出-上位机串口接收为例,对工作流程、工作模式和基本概念进行讲解,同时创建了主机类和传感器类,定义了属性和抽象方法。

原文链接:

FreakStudio 的博客

往期推荐:

可能是全网最适合入门的面向对象编程教程:Python实现-嵌入式爱好者必看!

全网最适合入门的面向对象编程教程:00 面向对象设计方法导论

全网最适合入门的面向对象编程教程:01 面向对象编程的基本概念

全网最适合入门的面向对象编程教程:02 类和对象的Python实现-使用Python创建类

全网最适合入门的面向对象编程教程:03 类和对象的Python实现-为自定义类添加属性

全网最适合入门的面向对象编程教程:04 类和对象的 Python 实现-为自定义类添加方法

全网最适合入门的面向对象编程教程:05 类和对象的Python实现-PyCharm代码标签

全网最适合入门的面向对象编程教程:06 类和对象的 Python 实现-自定义类的数据封装

全网最适合入门的面向对象编程教程:07 类和对象的Python实现-类型注解

全网最适合入门的面向对象编程教程:08 类和对象的 Python 实现-@property 装饰器

全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系

更多精彩内容可看:

CM3调试系统简析

肝了半个月,嵌入式技术栈大汇总出炉

比赛获奖的武林秘籍:03 好的创意选取-获得国奖的最必要前提

比赛获奖的武林秘籍:02 国奖秘籍-大学生电子计算机类竞赛快速上手的流程,小白必看

比赛获奖的武林秘籍:01 如何看待当代大学生竞赛中“卷”“祖传老项目”“找关系”的现象?

比赛获奖的武林秘籍:00 学科竞赛-工科类大学生绕不开的话题,你了解多少?

电子计算机类比赛的“武林秘籍”-电赛光电设计大赛计算机设计大赛嵌入式芯片与系统设计竞赛,你要的都在这里!

文档和代码获取

可访问如下链接进行对文档下载:

https://github.com/leezisheng/Doc

image

本文档主要介绍如何使用 Python 进行面向对象编程,需要读者对 Python 语法和单片机开发具有基本了解。相比其他讲解 Python 面向对象编程的博客或书籍而言,本文档更加详细、侧重于嵌入式上位机应用,以上位机和下位机的常见串口数据收发、数据处理、动态图绘制等为应用实例,同时使用 Sourcetrail 代码软件对代码进行可视化阅读便于读者理解。

相关示例代码获取链接如下:https://github.com/leezisheng/Python-OOP-Demo

正文

类的继承的基本概念

刚才我们提到了,可以在已有类的基础上创建新类,这其中的一种做法就是让一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写。提供继承信息的我们称之为父类,也叫超类或基类;得到继承信息的我们称之为子类,也叫派生类或衍生类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力,在实际开发中,我们经常会用子类对象去替换掉一个父类对象,这是面向对象编程中一个常见的行为,对应的原则称之为里氏替换原则

里氏替换原则

所谓里氏替换原则通俗来说就是子类可以扩展父类的功能,但不能改变父类原有的功能。有以下几个引申含义:

  • (1)子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • (2)子类中可以增加自己特有的方法。
  • (3)当子类的方法重载父类的方法时,方法的前置条件(方法的输入,入参)要比父类的入参更宽松。
  • (4)当子类的方法实现父类的方法时(重写,重载,实现抽象方法),方法的后置条件(输出、返回值)要比父类更严格或相等。

更多相关信息可以看:https://www.jyt0532.com/2020/03/22/lsp/

应用实例的抽象实现

这里,我们以模拟传感器数据串口输出-上位机串口接收为例,进行讲解:在现在的开发中,许多传感器都内部集成了 ADC 和 MCU 芯片,可以将采集到的传感器测量的物理量对应的电压量进行转换并进行滤波等处理后,将更精确的传感器数据通过串口进行输出。这里,传感器和上位机间关于串口通信的部分就可以抽象为串口类,二者都具有串口的收发功能。但传感器类和上位机接收类与串口类有有所不同:

image

SensorClass 类
类内成员作用
属性 attribute:sensorvalue传感器采集的数据
属性 attribute:sensorid传感器 ID 号,用于识别是哪个传感器
** **** **属性 attribute:sensorstate传感器工作状态,包括:** ① 被动响应模式(默认):主机发送查询数据指令后,传感器发送数据;**** ② 轮询工作模式:间隔 100ms 发送一个传感器数据,轮询工作;**
方法 operation:SendSensorID发送传感器 ID 号
方法 operation:SendSensorValue发送传感器采集的数据
方法 operation:RecvMasterCMD接收主机指令
方法 operation:StartSensor开始传感器工作
方法 operation:StopSensor停止传感器工作
方法 operation:InitSensor初始化传感器

工作流程简单来说就是传感器初始化后开始工作,不断采集数据,接收到主机发送的查询数据命令后,发送传感器数据;对应的接收到主机发送的不同指令后执行对应操作。

我们来看如下示例代码,SensorClass 类具体方法实现先省略:

class SensorClass(SerialClass):
    _# 类的初始化_
    def __init__(self,id,state):
        _# 调用父类的初始化方法,super() 函数将父类和子类连接_
        super().__init__()
        self.sensorvalue = 0
        self.sensorid    = id
        self.sensorstate = state

    _# 传感器上电初始化_
    def InitSensor(self):
        pass
    _# 开启传感器_
    def StartSensor(self):
        pass
    _# 停止传感器_
    def StopSensor(self):
        pass
    _# 发送传感器ID号_
    def SendSensorID(self):
        pass
    _# 发送传感器数据_
    def SendSensorValue(self):
        pass

这里,继承语法为:

class 派生类名(基类名)
    ...

在 SensorClass 类的初始化方法中,我们首先调用如下语句:

super().__init__()

这里,super()用来调用父类(基类)的方法,init()是类的构造方法, super().init() 就是调用父类的 init 方法, 同样可以使用 super()去调用父类的其他方法。这里,你可能会问,我们为何不用如下语句来初始化父类 SerialClass 呢?

SerialClass.__init__()

这看起来多清晰、多方便。实际上,super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。这里,不对钻石继承问题做过多叙述,只需知道子类初始化时必须调用 super() 方法。

有关钻石继承问题可以查看如下链接:

https://blog.csdn.net/qq_41556318/article/details/84521836

对于主机的 MasterClass 类来说,除了继承于父类 SerialClass 的属性和方法外,还包括其他属性和方法,如下讲解:

MasterClass 类
类内成员作用
属性 attribute:valuequeue主机中传感器采集数据的缓存队列
属性 attribute:masterstate**主机状态,包括:****① 空闲状态(默认):主机工作空闲,可以接收数据;**② 忙碌状态:主机工作忙碌,暂时停止数据接收。
方法 operation:RecvSensorID接收传感器 ID 号
方法 operation:RecvSensorValue接收传感器采集的数据
方法 operation:SendSensorCMD发送主机指令
方法 operation:StartMaster开始主机工作
方法 operation:StopMaster停止主机工作
方法 operation:RetMasterState返回主机状态

工作流程简单来说就是主机在空闲时,发送数据查询指令,接收传感器数据;在忙碌时,不接收数据。

我们来看如下示例代码,MasterClass 类具体方法实现先省略:

class MasterClass(SerialClass):
    _# 类的初始化_
    def __init__(self,state):
        _# 调用父类的初始化方法,super() 函数将父类和子类连接_
        super().__init__()
        self.valuequeue  = queue.Queue(5)
        self.masterstatue = state
    _# 开启主机_
    def StartMaster(self):
        pass
    _# 停止主机_
    def StopMaster(self):
        pass
    _# 接收传感器ID号_
    def RecvSensorID(self):
        pass
    _# 接收传感器数据_
    def RecvSensorValue(self):
        pass
    _# 主机发送命令_
    def SendSensorCMD(self):
        pass
    _# 主机返回工作状态_
    def RetMasterStatue(self):
        pass

这里,我们使用队列创建了一个传感器数据缓冲区:

self.valuequeue  = queue.Queue(5)

我们使用 import queue 语句导入队列库,队列类似于一条管道,元素先进先出,元素进入使用 put()方法,元素获取使用 get( )方法。关于新建的两个类方法的具体实现可以看下一节内容。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/779581.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣hot100-普通数组

文章目录 题目:最大子数组和方法1 动态规划方法2 题目:合并区间题解 题目:轮转数组方法1-使用额外的数组方法2-三次反转数组 题目:除自身以外数组的乘积方法1-用到了除法方法2-前后缀乘积法 题目:最大子数组和 原题链…

Mysql5.7并发插入死锁问题

死锁的产生条件 互斥、请求和保持、不可剥夺、循环等待 MySQL锁类型 死锁复现 环境:Mysql 5.7版本,Innodb引擎,可重复度隔离级别 并发场景下使用duplicate key update插入或更新数据可能会造成死锁,下面就产生死锁的条件进行模…

【扩散模型】LCM LoRA:一个通用的Stable Diffusion加速模块

潜在一致性模型:[2310.04378] Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (arxiv.org) 原文:Paper page - Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (…

Java常见面试题汇总带答案

本文分为十九个模块,分别是: Java 基础、容器、多线程、反射、对象拷贝、Java Web 、异常、网 络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、 Kafka、Zookeeper、MySQL、Redis、JVM 等等… JDK 和 JRE 有什么区别? JDK:Jav…

《基于 defineProperty 实现前端运行时变量检测》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,欢迎多多交流~ &am…

Threejs环境、透视相机、坐标系、光源

文章目录 如何引入threejsnpm方式script方式script module方式 基本流程与坐标摄像机Geometry(几何体)和Material(材质)光源 如何引入threejs 对于很多刚刚上手threejs的朋友,可能第一步引入threejs就出问题了, 明明已经导入了,就是这样问题…

scala基础

scala基础: hello world: 写scala可运行文件的注意事项1、如果一个scala文件要运行,class要改成object2、如果是class,就仅单纯代表一个类,如果是object代表的是单例对象3、scala语法中,一句话结束不需要加分号4、scal…

Linux——进程间通信一(共享内存、管道、systrem V)

一、进程间通信介绍 1.1、进程间通信的概念和意义 进程间通信(IPC interprocess communication)是一组编程接口,让不同进程之间相互传递、交换信息(让不同的进程看到同一份资源) 数据传输:一个进程需要将它的数据发送给另外一个进程 资源共享:多个进程之间共享同样…

Hadoop-16-Hive HiveServer2 HS2 允许客户端远程执行HiveHQL HCatalog 集群规划 实机配置运行

章节内容 上一节我们完成了: Metastore的基础概念配置模式:内嵌模式、本地模式、远程模式实机配置远程模式 并测试 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。 之前已经在 V…

Hadoop-YARN-Tutorial

Hadoop-YARN-Tutorial 1 What is YARN? Yarn is the acronym for yet another resource negotiator. Yarn是yet another resource negotiator的缩写。 Yarn is a resource manager created by separating the processing engine and the management function of mapreduce. …

YOLOv8_obb数据集可视化[旋转目标检测实践篇]

先贴代码,周末再补充解析。 这个篇章主要是对标注好的标签进行可视化,虽然比较简单,但是可以从可视化代码中学习到YOLOv8是如何对标签进行解析的。 import cv2 import numpy as np import os import randomdef read_obb_labels(label_file_path):with open(label_file_path,…

ViewController 生命周期

ViewController 生命周期 ViewController 生命周期测试程序:ViewControllerLifeCircle ViewController 生命周期 ViewController 是 iOS 开发中 MVC 框架中的 C,ViewColllecter 是 View(视图)的 Collecter(控制器&…

Vim编辑器与Shell命令脚本

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、Vim文本编辑器 二、编写Shell脚本 三、流程控制语句 四、计划任务服务程序 致谢 一、Vim文本编辑器 “在Linux系统中一切都是文件&am…

TQ15EG开发板教程:MPSOC创建fmcomms8工程

链接:https://pan.baidu.com/s/1jbuYs9alP2SaqnV5fpNgyg 提取码:r00c 本例程需要实现在hdl加no-OS系统中,通过修改fmcomms8/zcu102项目,实现在MPSOC两个fmc口上运行fmcomms8项目。 目录 1 下载文件与切换版本 2 编译fmcomms8项…

【SpringCloud】概述 -- 微服务入门

在Java的整个学习过程中,大家势必会听见一些什么分布式-微服务、高并发、高可用这些专业术语,给人的感觉很高级,有一种高深莫测的感觉。可以看一下这篇博客对这些技术架构的演变有一个初步的认识: 服务端⾼并发分布式结构演进之路-CSDN博客文…

Java开源ERP系统Axelor汉化方法初探

Axelor简介 汉化过程介绍 定义语言和本地化 导出多语言记录 导入翻译 验证翻译 调整翻译 Axelor简介 2024年6月份Axelor ERP发布了8.1版本,适配JDK11及PostgreSQL12及以上版本(7及以前版本适配JDK8及PostgreSQL10)数据库。v8版本较之前…

kubernetes集群部署:node节点部署和cri-docker运行时安装(四)

安装前准备 同《kubernetes集群部署:环境准备及master节点部署(二)》 安装cri-docker 在 Kubernetes 1.20 版本之前,Docker 是 Kubernetes 默认的容器运行时。然而,Kubernetes 社区决定在 Kubernetes 1.20 及以后的…

昇思MindSpore学习入门-评价指标

当训练任务结束,常常需要评价函数(Metrics)来评估模型的好坏。不同的训练任务往往需要不同的Metrics函数。例如,对于二分类问题,常用的评价指标有precision(准确率)、recall(召回率&…

代码随想录算法训练Day58|LeetCode417-太平洋大西洋水流问题、LeetCode827-最大人工岛

太平洋大西洋水流问题 力扣417-太平洋大西洋水流问题 有一个 m n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。 这个岛被分割成一个由若干方形单元格组成的网格。给定一个…

调度系统揭秘(下):调度算法与架构设计

文章目录 一、调度算法1.1、广度优先:1.2、深度优先1.3、总结广度优先搜索(BFS)深度优先搜索(DFS) 二、架构设计2.1、Master/Slave架构优劣分析 2.2、Leader架构优劣分析 2.3、总结 一、调度算法 在调度系统中,调度算…