Python入门(10)--面向对象进阶
Python面向对象进阶 🚀
1. 继承与多态 🔄
1.1 继承基础
class Animal:def __init__(self, name, age):self.name = nameself.age = agedef speak(self):passdef describe(self):return f"{self.name} is {self.age} years old"class Dog(Animal):def __init__(self, name, age, breed):super().__init__(name, age) # 调用父类的初始化方法self.breed = breeddef speak(self):return f"{self.name} says Woof!"def describe(self):# 扩展父类的方法return f"{super().describe()} and is a {self.breed}"class Cat(Animal):def __init__(self, name, age, indoor=True):super().__init__(name, age)self.indoor = indoordef speak(self):return f"{self.name} says Meow!"def describe(self):habitat = "indoor" if self.indoor else "outdoor"return f"{super().describe()} and is an {habitat} cat"# 使用示例
dog = Dog("Buddy", 3, "Golden Retriever")
cat = Cat("Whiskers", 2, True)print(dog.describe()) # 输出: Buddy is 3 years old and is a Golden Retriever
print(cat.describe()) # 输出: Whiskers is 2 years old and is an indoor cat
继承的关键概念:
super()
的使用:调用父类方法- 方法重写与扩展
- 构造函数的继承与扩展
- 属性的继承与新增
1.2 多态
让我们通过一个更实际的例子来展示多态的威力:
class Document:def __init__(self, content):self.content = contentdef format(self):passclass PlainText(Document):def format(self):return self.contentclass HTMLDocument(Document):def format(self):return f"<html><body>{self.content}</body></html>"class MarkdownDocument(Document):def format(self):return f"# {self.content}"def process_documents(documents):"""多态函数 - 统一处理不同类型的文档"""for doc in documents:print(f"处理 {doc.__class__.__name__}:")print(doc.format())print("---")# 实际应用
documents = [PlainText("Hello World"),HTMLDocument("Welcome"),MarkdownDocument("Title")
]process_documents(documents)
1.3 多重继承
让我们通过一个更实用的场景来展示多重继承:
class Persistable:"""提供持久化功能的混入类"""def save(self, filename):with open(filename, 'w') as f:f.write(str(self.__dict__))def load(self, filename):with open(filename, 'r') as f:data = eval(f.read())self.__dict__.update(data)class Loggable:"""提供日志功能的混入类"""def log(self, message):print(f"[{self.__class__.__name__}] {message}")class Configuration(Persistable, Loggable):"""应用配置类"""def __init__(self, host="localhost", port=8000):self.host = hostself.port = portdef update_config(self, **kwargs):self.log("Updating configuration...")self.__dict__.update(kwargs)self.log("Configuration updated")# 使用示例
config = Configuration()
config.update_config(host="127.0.0.1", port=5000)
config.save("config.txt") # 保存配置
config.load("config.txt") # 加载配置
2. 封装与访问控制 🔒
让我们通过一个更完整的例子来展示Python的封装机制:
class Employee:def __init__(self, name, salary):self._name = name # 受保护的属性self.__salary = salary # 私有属性self.__bonus = 0 # 私有属性@propertydef name(self):"""只读属性"""return self._name@propertydef total_salary(self):"""计算总薪资(基本工资 + 奖金)"""return self.__salary + self.__bonus@propertydef bonus(self):"""奖金查询"""return self.__bonus@bonus.setterdef bonus(self, value):"""设置奖金,带验证"""if not isinstance(value, (int, float)):raise TypeError("奖金必须是数字")if value < 0:raise ValueError("奖金不能为负数")self.__bonus = valuedef _calculate_tax(self):"""受保护的方法 - 计算税收"""return self.total_salary * 0.2def get_salary_info(self):"""公开方法 - 获取薪资信息"""return {'name': self._name,'total_salary': self.total_salary,'tax': self._calculate_tax(),'net_salary': self.total_salary - self._calculate_tax()}# 使用示例
emp = Employee("John Doe", 5000)# 属性访问
print(emp.name) # 使用@property
emp.bonus = 1000 # 使用@bonus.setter
print(emp.total_salary) # 使用@property计算总薪资# 获取完整信息
salary_info = emp.get_salary_info()
for key, value in salary_info.items():print(f"{key}: {value}")# 以下操作会引发错误
# emp.name = "Jane" # AttributeError: 不能修改只读属性
# emp.__salary = 6000 # AttributeError: 私有属性不能直接访问
# emp.bonus = -100 # ValueError: 奖金不能为负数
补充说明:
- 使用
@property
创建只读属性 - 使用
@property
和@x.setter
创建可读写属性 - 使用单下划线表示受保护成员
- 使用双下划线表示私有成员
- 通过公开方法提供对私有数据的安全访问
3. 类方法与静态方法 🛠️
3.1 类方法(@classmethod)
让我们通过一个更实用的工厂模式示例来展示类方法的应用:
from datetime import datetime, dateclass Order:"""订单类"""order_count = 0 # 类变量,用于追踪订单数量def __init__(self, customer_id: str, items: list, order_date: date):Order.order_count += 1self.order_id = f"ORD{Order.order_count:04d}"self.customer_id = customer_idself.items = itemsself.order_date = order_dateself.status = "pending"@classmethoddef create_from_dict(cls, order_data: dict):"""从字典创建订单对象"""try:customer_id = order_data['customer_id']items = order_data['items']# 解析日期字符串date_str = order_data.get('date', datetime.now().strftime('%Y-%m-%d'))order_date = datetime.strptime(date_str, '%Y-%m-%d').date()return cls(customer_id, items, order_date)except KeyError as e:raise ValueError(f"缺少必要的订单信息: {e}")@classmethoddef create_rush_order(cls, customer_id: str, items: list):"""创建加急订单"""order = cls(customer_id, items, date.today())order.status = "rush"return order@classmethoddef get_order_count(cls) -> int:"""获取订单总数"""return cls.order_countdef __str__(self):return f"Order {self.order_id}: {len(self.items)} items for {self.customer_id}"# 使用示例
# 1. 常规创建
order1 = Order("CUST001", ["item1", "item2"], date.today())# 2. 从字典创建
order_data = {"customer_id": "CUST002","items": ["item3", "item4"],"date": "2024-03-15"
}
order2 = Order.create_from_dict(order_data)# 3. 创建加急订单
rush_order = Order.create_rush_order("CUST003", ["urgent_item"])print(f"Total orders: {Order.get_order_count()}") # 输出订单总数
3.2 静态方法(@staticmethod)
通过一个更复杂的示例来展示静态方法的实际应用:
class DataValidator:"""数据验证工具类"""@staticmethoddef validate_email(email: str) -> bool:"""验证邮箱格式"""import repattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'return bool(re.match(pattern, email))@staticmethoddef validate_phone(phone: str) -> bool:"""验证电话号码格式"""import re# 支持多种格式:+86-123-4567-8901, 12345678901, 123-4567-8901patterns = [r'^\+\d{1,3}-\d{3}-\d{4}-\d{4}$',r'^\d{11}$',r'^\d{3}-\d{4}-\d{4}$']return any(bool(re.match(pattern, phone)) for pattern in patterns)@staticmethoddef validate_date(date_str: str) -> bool:"""验证日期格式和有效性"""try:datetime.strptime(date_str, '%Y-%m-%d')return Trueexcept ValueError:return False@staticmethoddef sanitize_string(text: str) -> str:"""清理并验证字符串"""# 移除首尾空白,替换多个空格为单个空格text = ' '.join(text.split())# 移除特殊字符text = ''.join(char for char in text if char.isprintable())return textclass UserProfile:"""用户档案类 - 展示数据验证的应用"""def __init__(self, email: str, phone: str, birth_date: str):if not DataValidator.validate_email(email):raise ValueError("无效的邮箱地址")if not DataValidator.validate_phone(phone):raise ValueError("无效的电话号码")if not DataValidator.validate_date(birth_date):raise ValueError("无效的出生日期")self.email = emailself.phone = phoneself.birth_date = birth_date# 使用示例
try:# 创建用户档案user = UserProfile(email="john.doe@example.com",phone="123-4567-8901",birth_date="1990-01-01")print("用户档案创建成功")# 验证和清理数据text = " Hello World! \n\t@#$% "cleaned = DataValidator.sanitize_string(text)print(f"清理后的文本: '{cleaned}'")except ValueError as e:print(f"错误: {e}")
4. 抽象类与接口 🎯
让我们通过一个文件处理系统的例子来展示抽象类和接口的实际应用:
from abc import ABC, abstractmethod
from typing import Any, List, Dict
import json
import csv
import xml.etree.ElementTree as ETclass DataProcessor(ABC):"""数据处理器抽象基类"""@abstractmethoddef read(self, source: str) -> Any:"""读取数据"""pass@abstractmethoddef write(self, data: Any, destination: str) -> bool:"""写入数据"""pass@abstractmethoddef validate(self, data: Any) -> bool:"""验证数据"""pass@property@abstractmethoddef supported_extensions(self) -> List[str]:"""支持的文件扩展名"""passclass JSONProcessor(DataProcessor):"""JSON数据处理器"""@propertydef supported_extensions(self) -> List[str]:return ['.json']def validate(self, data: Any) -> bool:if not isinstance(data, (dict, list)):return Falsetry:json.dumps(data) # 测试是否可序列化return Trueexcept (TypeError, ValueError):return Falsedef read(self, source: str) -> Any:try:with open(source, 'r', encoding='utf-8') as f:return json.load(f)except json.JSONDecodeError as e:raise ValueError(f"JSON解析错误: {e}")def write(self, data: Any, destination: str) -> bool:if not self.validate(data):raise ValueError("无效的JSON数据")try:with open(destination, 'w', encoding='utf-8') as f:json.dump(data, f, indent=2, ensure_ascii=False)return Trueexcept Exception as e:print(f"写入错误: {e}")return Falseclass CSVProcessor(DataProcessor):"""CSV数据处理器"""@propertydef supported_extensions(self) -> List[str]:return ['.csv']def validate(self, data: Any) -> bool:return isinstance(data, list) and all(isinstance(row, dict) for row in data)def read(self, source: str) -> List[Dict]:try:with open(source, 'r', encoding='utf-8') as f:return list(csv.DictReader(f))except Exception as e:raise ValueError(f"CSV读取错误: {e}")def write(self, data: List[Dict], destination: str) -> bool:if not self.validate(data):raise ValueError("无效的CSV数据格式")try:with open(destination, 'w', newline='', encoding='utf-8') as f:if not data:return Truewriter = csv.DictWriter(f, fieldnames=data[0].keys())writer.writeheader()writer.writerows(data)return Trueexcept Exception as e:print(f"写入错误: {e}")return Falseclass DataProcessorFactory:"""数据处理器工厂"""_processors: Dict[str, DataProcessor] = {'.json': JSONProcessor(),'.csv': CSVProcessor()}@classmethoddef get_processor(cls, file_path: str) -> DataProcessor:"""根据文件扩展名获取相应的处理器"""import osext = os.path.splitext(file_path)[1].lower()processor = cls._processors.get(ext)if not processor:raise ValueError(f"不支持的文件类型: {ext}")return processor# 使用示例
def convert_file(source: str, destination: str):"""文件转换功能"""try:# 获取源文件和目标文件的处理器source_processor = DataProcessorFactory.get_processor(source)dest_processor = DataProcessorFactory.get_processor(destination)# 读取源文件data = source_processor.read(source)# 写入目标文件if dest_processor.write(data, destination):print(f"文件转换成功: {source} -> {destination}")else:print("文件转换失败")except Exception as e:print(f"转换错误: {e}")# 测试文件转换
if __name__ == "__main__":# JSON到CSV的转换convert_file("data.json", "output.csv")# CSV到JSON的转换convert_file("data.csv", "output.json")
5. 实战案例:图形计算器 📐
让我们创建一个图形计算器,它能够处理不同类型的图形,计算它们的面积和周长:
from abc import ABC, abstractmethod
from typing import List
import mathclass Shape(ABC):"""抽象基类:形状"""@abstractmethoddef area(self) -> float:"""计算面积"""pass@abstractmethoddef perimeter(self) -> float:"""计算周长"""pass@abstractmethoddef description(self) -> str:"""返回形状描述"""passclass Rectangle(Shape):"""矩形类"""def __init__(self, width: float, height: float):if width <= 0 or height <= 0:raise ValueError("矩形的宽和高必须为正数")self._width = widthself._height = heightdef area(self) -> float:return self._width * self._heightdef perimeter(self) -> float:return 2 * (self._width + self._height)def description(self) -> str:return f"矩形(宽={self._width}, 高={self._height})"class Circle(Shape):"""圆形类"""def __init__(self, radius: float):if radius <= 0:raise ValueError("圆的半径必须为正数")self._radius = radiusdef area(self) -> float:return math.pi * self._radius ** 2def perimeter(self) -> float:return 2 * math.pi * self._radiusdef description(self) -> str:return f"圆形(半径={self._radius})"class Triangle(Shape):"""三角形类"""def __init__(self, a: float, b: float, c: float):if not self._is_valid_triangle(a, b, c):raise ValueError("无效的三角形边长")self._sides = (a, b, c)@staticmethoddef _is_valid_triangle(a: float, b: float, c: float) -> bool:"""检查三条边是否能构成三角形"""return (a > 0 and b > 0 and c > 0 anda + b > c and b + c > a and a + c > b)def area(self) -> float:"""使用海伦公式计算面积"""a, b, c = self._sidess = (a + b + c) / 2 # 半周长return math.sqrt(s * (s - a) * (s - b) * (s - c))def perimeter(self) -> float:return sum(self._sides)def description(self) -> str:return f"三角形(边长={', '.join(map(str, self._sides))})"class GeometryCalculator:"""几何计算器类"""def __init__(self):self._shapes: List[Shape] = []def add_shape(self, shape: Shape):"""添加形状"""self._shapes.append(shape)print(f"已添加: {shape.description()}")def calculate_total_area(self) -> float:"""计算所有形状的总面积"""return sum(shape.area() for shape in self._shapes)def calculate_total_perimeter(self) -> float:"""计算所有形状的总周长"""return sum(shape.perimeter() for shape in self._shapes)def show_all_shapes(self):"""显示所有形状的信息"""print("\n形状列表:")for i, shape in enumerate(self._shapes, 1):print(f"{i}. {shape.description()}")print(f" 面积: {shape.area():.2f}")print(f" 周长: {shape.perimeter():.2f}")def main():# 创建计算器实例calculator = GeometryCalculator()# 添加一些形状try:calculator.add_shape(Rectangle(5, 3))calculator.add_shape(Circle(4))calculator.add_shape(Triangle(3, 4, 5))# 显示所有形状信息calculator.show_all_shapes()# 显示总计print(f"\n总面积: {calculator.calculate_total_area():.2f}")print(f"总周长: {calculator.calculate_total_perimeter():.2f}")except ValueError as e:print(f"错误: {e}")if __name__ == "__main__":main()
实战案例特点:
- 抽象基类:使用
Shape
作为抽象基类,定义了必须实现的方法 - 继承与多态:各种具体图形类继承自
Shape
类 - 封装:使用私有属性保护数据
- 类型提示:使用
typing
模块增加代码可读性 - 错误处理:包含适当的验证和异常处理
- 静态方法:用于辅助功能(如三角形的有效性检查)
扩展建议:
- 添加更多图形类型(如多边形、椭圆等)
- 实现图形的缩放和旋转
- 添加图形的绘制功能
- 实现文件保存和加载功能
- 添加图形组合功能
- 实现简单的GUI界面
- 添加单位转换功能
这个实战案例展示了面向对象编程的进阶概念,包括继承、多态、封装和抽象类的实际应用。它提供了一个可扩展的框架,可以根据需要添加更多功能。
如果你觉得这篇文章有帮助,欢迎点赞转发,也期待在评论区看到你的想法和建议!👇
咱们下一期见!
相关文章:

Python入门(10)--面向对象进阶
Python面向对象进阶 🚀 1. 继承与多态 🔄 1.1 继承基础 class Animal:def __init__(self, name, age):self.name nameself.age agedef speak(self):passdef describe(self):return f"{self.name} is {self.age} years old"class Dog(Anim…...

Makefile 之 自动化变量
作用范围只在这条规则以及连带规则中,所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。 "$" 表示目标的集合,就像一个数组,"$"依次取出目标,并执于命令。 "$<"和"$&qu…...

鸿蒙开发:ForEach中为什么键值生成函数很重要
前言 在列表组件使用的时候,如List、Grid、WaterFlow等,循环渲染时都会使用到ForEach或者LazyForEach,当然了,也有单独使用的场景,如下,一个很简单的列表组件使用,这种使用方式,在官…...

沃丰科技智能外呼机器人:超越人工,重塑外呼体验
随着科技的不断发展,人工智能已经逐渐渗透到各行各业,其中智能外呼机器人的出现,更是给企业带来了全新的客户体验。与传统的人工外呼相比,智能外呼机器人具有更高的效率、更低的成本以及更好的用户体验等优势。 优势一࿱…...

百度飞浆:paddle 线性回归模型
学习引用 参考视频: https://www.bilibili.com/video/BV1oRtkeVEVx?spm_id_from333.788.player.switch&vd_sourcec7739de98d044e74cdc74d6e772bed5f&p2 这段代码使用PaddlePaddle深度学习框架来实现一个简单的线性回归模型,旨在从给定的出租车…...

【JavaSE】【网络编程】UDP数据报套接字编程
目录 一、网络编程简介二、Socket套接字三、TCP/UDP简介3.1 有连接 vs 无连接3.2 可靠传输 vs 不可靠传输3.3 面向字节流 vs 面向数据报3.4 双向工 vs 单行工 四、UDP数据报套接字编程4.1 API介绍4.1.1 DatagramSocket类4.1.1.1 构造方法4.1.1.2 主要方法 4.1.2 DatagramPocket…...

45.坑王驾到第九期:Mac安装typescript后tsc命令无效的问题
点赞收藏加关注,你也能主打别墅! 一、问题描述 Mac上终端运行如下命令: sudo npm install typescript -g //全局安装ts提示成功安装后,我测试tsc -v这个命令时出现如下错误: 也就是说找不到 tsc 命令。 二、解决方…...

20241120-Milvus向量数据库快速体验
目录 20241120-Milvus向量数据库快速体验Milvus 向量数据库pymilvus内嵌向量数据库模式设置向量数据库创建 Collections准备数据用向量表示文本插入数据 语义搜索向量搜索带元数据过滤的向量搜索查询通过主键搜索 删除实体加载现有数据删除 Collections了解更多 个人主页: 【⭐…...

【Golang】——Gin 框架中间件详解:从基础到实战
中间件是 Web 应用开发中常见的功能模块,Gin 框架支持自定义和使用内置的中间件,让你在请求到达路由处理函数前进行一系列预处理操作。这篇博客将涵盖中间件的概念、内置中间件的用法、如何编写自定义中间件,以及在实际应用中的一些最佳实践。…...

量子计算来袭:如何保护未来的数字世界
目录 前言 一、量子计算安全的学习方向 1. 量子物理学基础 2. 量子计算原理与技术 3. 传统网络安全知识 4. 量子密码学 5. 量子计算安全政策与法规 二、量子计算的漏洞风险 1. 加密算法被破解风险 2. 区块链安全风险 3. 量子密钥分发风险 4. 量子计算系统自身风险 …...

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源
VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源 由于需要在 Linux 环境下进行一些测试工作,于是决定使用 VMware 虚拟化软件来安装 Ubuntu 24.04 .1操作系统。考虑到测试过程中需要访问 Github ,要使用Docker拉去镜像等外部网络资源,因此产…...

光伏电站仿真系统的作用
光伏仿真系统有多方面的重要作用,不仅对前期的项目设计评估还是后期的运维效验都有非常重要的作用。 1、优化系统设计 通过输入不同的光伏组件参数、布局方案以及气象条件等,模拟各种设计场景下光伏电站的性能表现。例如,可以比较不同类型光…...

Golang文件操作
写文件 &emsp; os模块可以创建文件,使用fmt可以写入文件。如以下例子: package mainimport ("fmt""os" )func main() {// 学习 golang的文件操作file, err : os.Create("test.txt")if err ! nil {fmt.P…...

爬虫开发工具与环境搭建——使用Postman和浏览器开发者工具
第三节:使用Postman和浏览器开发者工具 在网络爬虫开发过程中,我们经常需要对HTTP请求进行测试、分析和调试。Postman和浏览器开发者工具(特别是Network面板和Console面板)是两种最常用的工具,能够帮助开发者有效地捕…...

React(二)
文章目录 项目地址七、数据流7.1 子组件传递数据给父组件7.1.1 方式一:給父设置回调函数,传递给子7.1.2 方式二:直接将父的setState传递给子7.2 给props传递jsx7.2.1 方式一:直接传递组件给子类7.2.2 方式二:传递函数给子组件7.3 props类型验证7.4 props的多层传递7.5 cla…...

同步原语(Synchronization Primitives)
同步原语(Synchronization Primitives)是用于控制并发编程中多个线程或进程之间的访问顺序,确保共享资源的安全访问的一组机制或工具。它们解决了竞争条件(Race Condition)、死锁(Deadlock)等并…...

SpringBoot服务多环境配置
一个项目的的环境一般有三个:开发(dev)、测试(test)、生产(proc),一般对应三套环境,三套配置文件。 像下面这样直接写两个配置文件是不行的。 application.ymlserver:port: 8080application-dev.ymlspring:datasource:driver-class-name: co…...

STM32单片机CAN总线汽车线路通断检测-分享
目录 目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 1.电路图采用Altium Designer进行设计: 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着汽车电子技术的不断发展,车辆通信接口在汽车电子控…...

【环境搭建】使用IDEA远程调试Docker中的Java Web
有时候要对Docker的Java Web远程调试其功能,于是就需要使用IDEA的远程调试功能,记录一下简单配置方法。 以Kylin4.0.0为例,首先拉取镜像并启动容器: $ docker pull apachekylin/apache-kylin-standalone:4.0.0$ docker run -d \-…...

贴代码框架PasteForm特性介绍之select,selects,lselect和reload
简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管…...

STM32G4的数模转换器(DAC)的应用
目录 概述 1 DAC模块介绍 2 STM32Cube配置参数 2.1 参数配置 2.2 项目架构 3 代码实现 3.1 接口函数 3.2 功能函数 3.3 波形源代码 4 DAC功能测试 4.1 测试方法介绍 4.2 波形测试 概述 本文主要介绍如何使用STM32G4的DAC模块功能,笔者使用STM32Cube工具…...

SpringMVC跨线程获取requests请求对象(子线程共享servletRequestAttributes)和跨线程获取token信息
文章目录 引言I 跨线程共享数据跨线程获取requests请求对象基于org.slf4j.MDC存储共享数据InheritableThreadLocal解决异步线程,无法获取token信息问题II Feign 传递请求属性feign 模块处理被调用方处理请求头III 异步调用的方式CompletableFutureAsync注解Executors引言 本文…...

提取repo的仓库和工作树(无效)
问题 从供应商处获取的.repo的git仓库裸(project-object)仓库和工作树(projects)是分开的。 解决方案 根据工作树的软链接路劲,将工作树合并到project-object下。 import os import shutil import argparse import logging# 设置日志配置 logging.basicConfig(l…...

力扣整理版七:二叉树(待更新)
满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。深度为k,有2^k-1个节点的二叉树。 完全二叉树:在完全二叉树中,除了最底层节点可能没填满外&am…...

基于单片机的多功能环保宠物窝设计
本设计基于单片机设计的多功能环保宠物窝,利用温湿度传感器、压力传感模块、气味传感模块、红外测温传感器、通信模块、显示模块、清扫部件等,使其能够实现自动检测并调节温湿度、补充宠物食物、检测宠物体温健康并出现异常时进行报警、自动清扫消毒宠物…...

HBase 基础操作
一、启动HBase 首先,确保Hadoop和HBase服务已经启动。如果尚未启动,可以使用以下命令启动: # 启动Hadoop start-all.sh# 启动HBase start-hbase.sh二、HBase Shell操作 创建表 在HBase Shell中,使用create命令创建表。以下是一…...

小米顾此失彼:汽车毛利大增,手机却跌至低谷
科技新知 原创作者丨依蔓 编辑丨蕨影 三年磨一剑的小米汽车毛利率大增,手机业务毛利率却出现下滑景象。 11月18日,小米集团发布 2024年第三季度财报,公司实现营收925.1亿元,同比增长30.5%,预估902.8亿元;…...

PCL 三维重建 a-shape曲面重建算法
目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 Concave Hull重建 2.1.2 可视化曲面重建结果 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更新) 一、概述 …...

【Android】线程池的解析
引言 在Android当中根据用途分为主线程与子线程,主线程当中主要处理与界面相关的操作,子线程主要进行耗时操作。除了Thread本身以外,在Android当中还有很多扮演者线程的角色,比如AsyncTask( 底层为线程池,…...

集群聊天服务器(8)用户登录业务
目录 登录状态业务层代码数据模型层代码记录用户的连接信息以及线程安全问题客户端异常退出业务 登录状态 登录且状态变为online 业务层代码 #include "chatservice.hpp" #include "public.hpp" #include <string> #include <muduo/base/Loggi…...