当前位置: 首页 > news >正文

多态:面向对象编程的重要特性

摘要:本文全面阐述了面向对象编程中多态这一关键特性,从多态的形式、使用场景、定义及前提条件出发,深入分析其运行特点、弊端,详细介绍引用类型转换相关知识,并通过综合练习强化对多态的理解与应用,为深入掌握面向对象编程提供了有力支撑。

关键词:多态;继承;方法重写;引用类型转换
参考资料::黑马程序员

一、引言

多态作为面向对象的第三大特性,在继承或实现关系中发挥重要作用,极大地增强了程序的灵活性与扩展性。本文将系统地探讨多态的各个方面。

二、多态的形式

多态在继承或实现关系中得以体现,其常见格式为:

父类类型 变量名 = new 子类/实现类构造器;
变量名.方法名();

多态存在的前提是具有继承关系,子类对象能够赋值给父类类型变量。例如,Animal为动物类型,Cat为猫类型,Cat继承自Animal,那么Cat对象可赋值给Animal类型变量。

三、多态的使用场景

在未使用多态时,如register方法若仅能接收学生对象,对于TeacherAdministrator对象则需定义不同的register方法。

public void register(Student s){}

而借助多态,register方法的形参可定义为共同的父类Person
当方法形参为类时,可传递该类的所有子类对象;当形参为接口时,可传递该接口的所有实现类对象(后续学习),并且多态能够依据传递的不同对象调用不同类中的方法。

以代码示例说明:

// 父类
public class Person {private String name;private int age;// 空参构造public Person() {}// 带全部参数的构造public Person(String name, int age) {this.name = name;this.age = age;}// get和set方法public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void show() {System.out.println(name + ", " + age);}
}// 子类1
public class Administrator extends Person {@Overridepublic void show() {System.out.println("管理员的信息为:" + getName() + ", " + getAge());}
}// 子类2
public class Student extends Person {@Overridepublic void show() {System.out.println("学生的信息为:" + getName() + ", " + getAge());}
}// 子类3
public class Teacher extends Person {@Overridepublic void show() {System.out.println("老师的信息为:" + getName() + ", " + getAge());}
}// 测试类
public class Test {public static void main(String[] args) {// 创建三个对象,并调用register方法Student s = new Student();s.setName("张三");s.setAge(18);Teacher t = new Teacher();t.setName("王建国");t.setAge(30);Administrator admin = new Administrator();admin.setName("管理员");admin.setAge(35);register(s);register(t);register(admin);}// 这个方法既能接收老师,又能接收学生,还能接收管理员// 只能把参数写成这三个类型的父类public static void register(Person p) {p.show();}
}

PS:@Override 注解最主要的作用是帮助编译器进行检查,确保被注解的方法确实重写了父类中的方法。如果一个方法使用了 @Override 注解,但父类中不存在对应的方法,编译器会报错。这样可以避免因方法签名错误而导致的意外行为

四、多态的定义和前提

多态指同一行为具有多个不同表现形式。例如,CatDog同为动物,都有“吃”这一行为,但具体表现不同。
其前提条件如下:

  1. 继承或实现关系:类之间需存在继承或实现关系。
  2. 方法的重写:子类对父类方法进行重写,若无重写,多态意义不大。
  3. 父类引用指向子类对象:即采用父类类型 变量名 = new 子类类型();的格式,其中父类类型指子类对象继承的父类类型或实现的父接口类型。

五、多态的运行特点

  1. 调用成员变量时:编译阶段依据左边父类类型判断是否存在该成员变量,运行阶段也使用左边父类类型的成员变量值。
  2. 调用成员方法时:编译阶段检查左边父类是否存在该方法,运行阶段则执行右边子类重写后的方法。

以代码示例说明:

Fu f = new Zi();
// 编译看左边的父类中有没有name这个属性,没有就报错
// 在实际运行的时候,把父类name属性的值打印出来
System.out.println(f.name);// 编译看左边的父类中有没有show这个方法,没有就报错
// 在实际运行的时候,运行的是子类中的show方法
f.show();

六、多态的弊端

多态在编译阶段依赖左边父类类型,这导致若子类具有独有的功能,多态写法无法直接访问。例如:

class Animal {public void eat() {System.out.println("动物吃东西!");}
}class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  public void catchMouse() {  System.out.println("抓老鼠");  }  
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");  }  
}class Test {public static void main(String[] args) {Animal a = new Cat();a.eat();a.catchMouse();// 编译报错,编译看左边,Animal没有这个方法}
}

七、引用类型转换

7.1 为什么要转型

多态无法直接调用子类独有的方法,为实现对这些方法的调用,需要进行转型。回顾基本数据类型转换,存在自动转换(范围小的赋值给范围大的,如double d = 5;)和强制转换(范围大的赋值给范围小的,如int i = (int)3.14)。多态的转型分为向上转型(自动转换)与向下转型(强制转换)。

7.2 向上转型(自动转换)

向上转型是子类类型向父类类型自动转换的过程,当父类引用指向子类对象时即发生向上转型,格式为:

父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();

原因在于父类类型范围相对子类较大,例如Animal包含所有动物,而Cat只是其中一种,因此子类可自动转型给父类类型变量。

7.3 向下转型(强制转换)

向下转型是父类类型向子类类型的强制转换过程。对于已向上转型的子类对象,将父类引用转为子类引用需使用强制类型转换格式,即:

子类类型 变量名 = (子类类型) 父类变量名;
如:Aniaml a = new Cat();Cat c = (Cat) a;  

7.4 案例演示

为调用子类特有方法,需进行向下转型。以如下代码为例:
定义类:

abstract class Animal {  abstract void eat();  
}  class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  public void catchMouse() {  System.out.println("抓老鼠");  }  
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");  }  public void watchHouse() {  System.out.println("看家");  }  
}

定义测试类:

public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat(); 				// 调用的是 Cat 的 eat// 向下转型  Cat c = (Cat)a;       c.catchMouse(); 		// 调用的是 Cat 的 catchMouse}  
}

7.5 转型的异常

转型过程中可能出现问题,如下代码虽能编译通过,但运行时会抛出ClassCastException类型转换异常:

public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();               // 调用的是 Cat 的 eat// 向下转型  Dog d = (Dog)a;       d.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】}  
}

这是因为创建的是Cat类型对象,运行时无法转换为Dog对象。

7.6 instanceof关键字

为避免ClassCastException异常(ClassCastException 是 Java 中的一个运行时异常,当你尝试将一个对象强制转换为不兼容的类型时就会抛出该异常。),Java提供instanceof关键字用于校验引用变量类型,格式为:

变量名 instanceof 数据类型 
如果变量属于该数据类型或者其子类类型,返回true。
如果变量不属于该数据类型或者其子类类型,返回false

因此,转换前可先进行判断,代码如下:

public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();               // 调用的是 Cat 的 eat// 向下转型  if (a instanceof Cat){Cat c = (Cat)a;       c.catchMouse();        // 调用的是 Cat 的 catchMouse} else if (a instanceof Dog){Dog d = (Dog)a;       d.watchHouse();       // 调用的是 Dog 的 watchHouse}}  
}

7.7 instanceof新特性

JDK14引入新特性,可将判断和强转合并为一行:

// 新特性
// 先判断a是否为Dog类型,如果是,则强转成Dog类型,转换之后变量名为d
// 如果不是,则不强转,结果直接是false
if(a instanceof Dog d){d.lookHome();
} else if(a instanceof Cat c){c.catchMouse();
} else{System.out.println("没有这个类型,无法转换");
}

八、综合练习

8.1 需求

  1. 定义狗类:包含年龄、颜色属性,以及eat(String something)(表示吃的东西)和看家lookHome(无参数)方法。
  2. 定义猫类:包含年龄、颜色属性,以及eat(String something)逮老鼠catchMouse(无参数)方法。
  3. 定义Person类(饲养员):包含姓名、年龄属性,以及keepPet(Dog dog, String something)(喂养宠物狗)和keepPet(Cat cat, String something)(喂养宠物猫)方法,生成空参、有参构造及setget方法。
  4. 定义测试类:实现keepPet(Dog dog, String something)方法打印“年龄为30岁的老王养了一只黑颜色的2岁的狗,2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃”;keepPet(Cat cat, String something)方法打印“年龄为25岁的老李养了一只灰颜色的3岁的猫,3岁的灰颜色的猫眯着眼睛侧着头吃鱼”。
  5. 思考
    • DogCat均为Animal的子类,现有针对不同动物定义不同keepPet方法的方式较为繁琐,思考如何简化及体会简化后的好处。
    • 尽管DogCatAnimal的子类,但都有特有方法,思考如何在keepPet中调用这些特有方法。

8.2 代码示例

// 动物类(父类)
public class Animal {private int age;private String color;public Animal() {}public Animal(int age, String color) {this.age = age;this.color = color;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public void eat(String something) {System.out.println("动物在吃" + something);}
}// 猫类(子类)
public class Cat extends Animal {public Cat() {}public Cat(int age, String color) {super(age, color);}@Overridepublic void eat(String something) {System.out.println(getAge() + "岁的" + getColor() + "颜色的猫眯着眼睛侧着头吃" + something);}public void catchMouse() {System.out.println("猫抓老鼠");}}// 狗类(子类)
public class Dog extends Animal {public Dog() {}public Dog(int age, String color) {super(age, color);}// 行为// eat(String something)(something表示吃的东西)// 看家lookHome方法(无参数)@Overridepublic void eat(String something) {System.out.println(getAge() + "岁的" + getColor() + "颜色的狗两只前腿死死的抱住" + something + "猛吃");}public void lookHome() {System.out.println("狗在看家");}
}// 饲养员类
public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}// 饲养狗/*public void keepPet(Dog dog, String something) {System.out.println("年龄为" + age + "岁的" + name + "养了一只" + dog.getColor() + "颜色的" + dog.getAge() + "岁的狗");dog.eat(something);}// 饲养猫public void keepPet(Cat cat, String something) {System.out.println("年龄为" + age + "岁的" + name + "养了一只" + cat.getColor() + "颜色的" + cat.getAge() + "岁的猫");cat.eat(something);}*/// 想要一个方法,能接收所有的动物,包括猫,包括狗// 方法的形参:可以写这些类的父类 Animalpublic void keepPet(Animal a, String something) {if(a instanceof Dog d) {System.out.println("年龄为" + age + "岁的" + name + "养了一只" + a.getColor() + "颜色的" + a.getAge() + "岁的狗");d.eat(something);} else if(a instanceof Cat c) {System.out.println("年龄为" + age + "岁的" + name + "养了一只" + c.getColor() + "颜色的" + c.getAge() + "岁的猫");c.eat(something);} else {System.out.println("没有这种动物");}}
}// 测试类
public class Test {public static void main(String[] args) {// 创建对象并调用方法/*Person p1 = new Person("老王",30);Dog d = new Dog(2,"黑");p1.keepPet(d,"骨头");Person p2 = new Person("老李",25);Cat c = new Cat(3,"灰");p2.keepPet(c,"鱼");*/// 创建饲养员的对象Person p = new Person("老王",30);Dog d = new Dog(2,"黑");Cat c = new Cat(3,"灰");p.keepPet(d,"骨头");p.keepPet(c,"鱼");}
}

相关文章:

多态:面向对象编程的重要特性

摘要:本文全面阐述了面向对象编程中多态这一关键特性,从多态的形式、使用场景、定义及前提条件出发,深入分析其运行特点、弊端,详细介绍引用类型转换相关知识,并通过综合练习强化对多态的理解与应用,为深入…...

使用 Vue 开发登录页面的完整指南

一、项目搭建与基础配置 环境准备 使用 Vue CLI 或 Vite 创建项目,推荐组合:Vue3 Element Plus Vue Router npm create vuelatest npm install element-plus element-plus/icons-vue vue-router 全局配置(main.js) import { c…...

【Pandas】pandas DataFrame isin

Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...

Linux 网络接口 /sys/class/net/eth0 文件详解

以下是对 /sys/class/net/eth0 目录下每个文件或目录的详细讲解。这些文件是 Linux 系统中 sysfs 文件系统的一部分,提供了与网络接口(这里是 eth0)相关的配置和状态信息。每个文件或目录的内容反映了网络接口的特定属性或状态,通…...

java+postgresql+swagger-多表关联insert操作(九)

入参为json,然后根据需要对多张表进行操作: 入参格式: {"username": "车主01","usertel": "11111111111","useridtype": "2","useridcard": null,"proname&qu…...

Jsp技术入门指南【六】jsp脚本原理及隐式对象

Jsp技术入门指南【六】jsp脚本原理及隐式对象 前言一、JSP 脚本元素1.1 声明1.2 表达式1.3 脚本标签 二、JSP 的隐式对象是什么三、隐式对象详解outrequestsessionapplicationconfigexception 前言 在之前的博客中,我们已经介绍了JSP的环境搭建、编译文件查找以及生…...

邮件自动回复助手(Rasa/SMTP)实现教程

在现代办公场景中,处理大量邮件是一项既耗时又容易出错的任务。为了提升工作效率,我们可以利用自然语言处理(NLP)和邮件传输协议(SMTP)技术,构建一个智能的邮件自动回复助手。本文将详细介绍如何…...

【vLLM 学习】Aqlm 示例

vLLM 是一款专为大语言模型推理加速而设计的框架,实现了 KV 缓存内存几乎零浪费,解决了内存管理瓶颈问题。 更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/ 源代码:vllm-project/vllm from vllm import LLM, SamplingParams fr…...

《数据结构之美--链表oj练习》

链表oj题分享 1. 移除链表元素 题目: 思路分析: 根据题目描述,可以看出该题是要将满足条件的链表元素删除,并且返回新的头结点. 首先我们想到的肯定是直接遍历该链表然后对满足条件的元素进行删除,但删除某个元素时…...

杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其四

那今天我们就把Hot100的所有题都完结了吧,Hot100作为大多数人笔试题的入门之选,可以说是非常的经典了,但是俗话说得好,书读百遍,其意自现,我不支持反复地只刷部分算法题,但是我支持周期性地刷刷…...

SpringBoot私人西服系统开发与设计

概述 基于SpringBoot的私人西服系统项目,是一个实用的服装管理系统。该系统包含了西服选择、面料选择、预约管理等核心功能。 主要内容 1. 管理员功能模块 用户管理:管理注册用户信息服装款式管理:管理西服款式信息面料类别管理&#xff…...

2.2/Q2,Charls最新文章解读

文章题目:Association of uric acid to high-density lipoprotein cholesterol ratio with the presence or absence of hypertensive kidney function: results from the China Health and Retirement Longitudinal Study (CHARLS) DOI:10.1186/s12882-…...

云端免费训练 AI 大模型推荐(适用于个人学习)

学习 AI 大模型训练(如LLM、扩散模型等),云端服务器是必不可少的,因为大模型对算力(GPU/TPU)和内存要求极高。以下是 适合不同学习阶段 的云端服务器推荐,涵盖 免费、低成本、高性能 选项&#…...

《操作系统真象还原》第九章(2)——线程

《操作系统真象还原》第九章(2)——线程 文章目录 《操作系统真象还原》第九章(2)——线程前言多线程调度简单优先级调度的基础任务调度器和任务切换注册时钟中断处理函数实现调度器schedule实现任务切换函数switch_to启用线程调度…...

Windows程序包管理器WinGet实战

概述 WinGet,Windows Package Manager,Windows软件包管理器,开源在GitHub,GitHub Releases可下载,官方文档。 WinGet由一个命令行工具和一组用于在Windows 10/11等版本上安装应用的服务组成,可帮助用户快…...

【特殊场景应对1】视觉设计:信息密度与美学的博弈——让简历在HR视网膜上蹦迪的科学指南

写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...

番外篇 | SEAM-YOLO:引入SEAM系列注意力机制,提升遮挡小目标的检测性能

前言:Hello大家好,我是小哥谈。SEAM(Squeeze-and-Excitation Attention Module)系列注意力机制是一种高效的特征增强方法,特别适合处理遮挡和小目标检测问题。该机制通过建模通道间关系来自适应地重新校准通道特征响应。在遮挡小目标检测中的应用优势包括:1)通道注意力增强…...

Top100(26-30)

二叉树的中序遍历 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2] 示例 2: 输入:root [] 输出:[] 示例 3: 输入&#x…...

在 Vue 3 中将拆分后的数组合并回原数组

接上文Vue 3 中按照某个字段将数组分成多个数组_vue3怎么进行数组对象--分割对象-CSDN博客 方法一:使用 flat() 方法 // 假设这是拆分后的多维数组 const splitArrays [[{id: 1, category: A}, {id: 3, category: A}],[{id: 2, category: B}, {id: 5, category: …...

MyBatis如何配置数据库连接并实现交互?

如果你用过MyBatis,肯定知道它的核心功能之一就是数据库连接管理。但很多新手在第一次配置时总会遇到各种问题:数据源怎么配?连接池参数如何调优?XML和注解方式有什么区别?今天我们就来彻底搞懂MyBatis连接数据库的每一…...

PyTorch入门------卷积神经网络

前言 参考:神经网络 — PyTorch Tutorials 2.6.0cu124 文档 - PyTorch 深度学习库 一个典型的神经网络训练过程如下: 定义一个包含可学习参数(或权重)的神经网络 遍历输入数据集 将输入通过神经网络处理 计算损失(即…...

Qt官方案例知识点总结(图形视图——Colliding Mice)

Colliding Mice 案例 图元可重写下面的方法,返回一个QPainterPath(形状),该形状基于图形项自己的坐标系 返回的形状用于碰撞检测、命中测试等,形状越精确,那么碰撞检测等就越准确 不重写的话,默认取 boundingRect()…...

人工智能在后端开发中的革命:从架构到运维

后端开发作为应用程序的"大脑",正在经历人工智能带来的深刻变革。从智能API设计到自动化数据库优化,从异常预测到资源调度,AI技术正在重塑后端开发的各个方面。本文将全面探讨AI如何赋能现代后端系统开发,并通过实际案例展示这些技术的应用价值。 一、智能API开…...

电子电器架构 --- EOL 工厂刷写(产线)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...

AI数据分析与BI可视化结合:解锁企业决策新境界

大家好,今天我们来聊聊一个前沿而热门的话题——AI数据分析与BI可视化结合,如何携手推动企业决策迈向新高度。在数据爆炸的时代,企业如何高效利用这些数据,成为制胜的关键。AI数据分析与BI可视化的结合,正是解锁这一潜…...

深度学习3.2 线性回归的从零开始实现

3.2.1 生成数据集 %matplotlib inline import random import torch from d2l import torch as d2ldef synthetic_data(w, b, num_examples):# 生成特征矩阵X,形状为(num_examples, len(w)),符合标准正态分布X torch.normal(0, 1, (num_examples, len(w…...

ArcPy工具箱制作(下)

在上一篇博客中,我们已经初步了解了如何制作ArcPy工具箱,包括工具箱的基本概念、准备工作、脚本编写以及将脚本转换为工具箱的步骤。今天,我们将继续深入探讨ArcPy工具箱的制作,重点介绍一些进阶技巧和优化方法. 一、优化工具箱的…...

if/switch语句初始化功能

基础介绍 这个特性是在c17版本引入的,在这之前是不允许在if语句或者switch语句中使用赋值语句,不仅仅是if语句和switch语句,包括lambda表达式在c17版本也支持类在捕获表达式中支持赋值操作。言归正传,下面阐述这个特性的基本语法…...

cmake 语法大纲

1,基础语法 CMakeLists.txt 目录组织文件; *.cmake 脚本文件 运行: $ cmake -P xxx.cmake *.cmake 模块文件 include 命令来引用 模块文件。 自定义模块; cmake 预制模块; 单行注释 # com 括号注释 #…...

前端单元测试实战:如何开始?

实战:如何开始单元测试 1.安装依赖 npm install --save-dev jest2.简单的例子 首先,创建一个 sum.js 文件 ./sum.js function sum(a, b) {return a b; }module.exports sum;创建一个名为 sum.test.js 的文件,这个文件包含了实际测试内…...

《软件设计师》复习笔记(12.2)——成本管理、配置管理

目录 一、项目成本管理 1. 定义 2. 主要过程 3. 成本类型 4. 其他概念 真题示例: 二、软件配置管理 1. 定义 2. 主要活动 3. 配置项 4. 基线(Baseline) 5. 配置库类型 真题示例: 一、项目成本管理 1. 定义 在批准…...

edge browser for linux debian

下载地址 https://www.microsoft.com/en-us/edge/download?formMA13FJ 安装 # 下载安装包 wget https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/microsoft-edge-stable_135.0.3179.85-1_amd64.deb?brandM102 # 安装 sudo dpkg -i microsoft…...

Python读取Excel表格数据并写成JSON格式文件(精简版)

🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 1. 步骤步骤 1: 安装必要的库步骤 2: 读取Ex…...

服务器的算力已经被被人占用了,我如何能“无缝衔接”?

今天遇到一个问题,服务器已经被别人占用了,我又不知道什么时候他能结束,因此很难去训练自己的模型,隔一会去看看别人是否结束又太麻烦,于是便可以写这个脚本文件来自动检测服务器是否空闲,一有空闲就可以自…...

rulego-server是一个开源程序,是一个轻量级、无依赖性的工作流自动化平台。支持 iPaaS、流式计算和 AI 能力。

一、软件介绍 文末提供程序和源码下载学习 RuleGo-Server 是一个基于 RuleGo 构建的轻量级、高性能、模块化和集成友好的自动化工作流程平台。可用于自动化编排、iPaaS(集成平台即服务)、API 编排、应用编排、AI 编排、数据处理、IoT 规则引擎、AI 助手…...

『前端样式分享』联系我们卡片式布局 自适应屏幕 hover动效 在wikijs中使用 (代码拿来即用)

目录 预览效果分析要点响应式网格布局卡片样式:阴影和过渡效果 代码优化希望 长短不一的邮箱地址在左右居中的同时,做到左侧文字对齐(wikijs可用)总结 欢迎关注 『前端布局样式』 专栏,持续更新中 欢迎关注 『前端布局样式』 专栏,持续更新中…...

航电系统之通信技术篇

航电系统(航空电子系统)的通信技术是现代航空器的核心技术之一,其核心目标是实现飞行器内部各系统之间以及飞行器与外部设备(如地面控制中心、其他飞行器等)之间高效、可靠的信息交互。随着航空技术的不断发展&#xf…...

4.3 熟悉字符串处理函数

作为一名C语言初学者,掌握字符串处理函数是编程道路上不可或缺的一步。字符串是C语言中处理文本数据的基础,而标准库提供了一系列强大的字符串处理函数,极大地方便了我们的开发工作。本文将带领大家熟悉这些常用的字符串处理函数,…...

二叉树理论基础

二叉树种类 满二叉树:每个非叶子节点都有且只有两个子节点。 和完全二叉树:除了最底层外,其他各层都是满的;最底层的节点都集中在左侧。 二叉搜索树:对于任意节点 u,左子树上所有节 点的值都小于 u.val…...

yarn的三个资源调度策略

### YARN 的三种资源调度策略及其工作原理与区别 #### 1. **FIFO Scheduler (先进先出调度器)** FIFO Scheduler 是一种最简单的调度方式,所有的应用程序都按顺序排队等待执行。其基本逻辑如下: - 应用程序按照提交的时间先后顺序依次进入队列。 - 当集…...

leetcode0112. 路径总和-easy

1 题目:路径总和 官方标定难度:易 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true &#xff1…...

铁氧体和纳米晶:车载定制电感的材料选择

最近有个做车载产品的粉丝问到:我们的定制电感产品既会用到铁氧体磁芯,也会用到纳米晶磁芯,那么这两种材料,该如何选择呢? 要回答这个问题,我们首先要对两种材料做一个基本的对比。 铁氧体材料成本低&…...

MCP认证难题破解

一、MCP 认证体系现状与核心挑战 微软认证专家(MCP)体系在 2020 年后逐步向基于角色的认证转型,例如 Azure 管理员(AZ-104)、数据分析师(DP-100)等,传统 MCP 考试已被取代。当前备考的核心难题集中在以下方面: 1. 技术栈快速迭代 云原生技术占比提升:Azure 认证中,…...

ROS机器人一般用哪些传感器?

以下是ROS机器人常用传感器的分层详解及思维导图总结,涵盖传感器分类、核心参数、ROS支持及典型应用: 一、环境感知传感器 1. 视觉传感器 类型 原理 ROS支持 数据类型 典型型号/驱动 优缺点及应用场景 单目摄像头 单镜头成像,通过透视变换获取2D图像,依赖算法推断深度 驱…...

【ubuntu】在Linux Yocto的基础上去适配Ubuntu的wifi模块

一、修改wifi的节点名 1.找到wifi模块的PID和VID ifconfig查看wifi模块网络节点的名字,发现是wlx44876393bb3a(wlxmac地址) 通过udevadm info -a /sys/class/net/wlx44876393bba路径的命令去查看wlx44876393bba的总线号,端口号…...

基于WebRTC技术的EasyRTC:支持任意平台设备的实时音视频通信解决方案

一、技术架构与核心优势 EasyRTC是一套基于WebRTC技术的实时音视频通信框架,旨在为开发者提供高效、稳定、跨平台的通信解决方案。其核心优势在于支持任意平台设备,包括Web端、移动端、桌面端和嵌入式设备,真正实现“一次开发,多…...

51单片机实验四:键盘检测原理及应用实现

目录 一、实验环境与实验器材 二、实验内容及实验步骤 1.独立键盘检测 2.独立键盘(简易版本) 3.矩阵键盘检测 4.矩阵键盘(简单版,单数码管): 一、实验环境与实验器材 环境:Keli&#xff0c…...

GN ninja 工程化构建例程

文章目录 1. 前言✨2. 工程实例🚩2.1 工程目录结构2.2 工程顶层.gn文件2.3 工具链配置.gn文件2.4 编译配置.gn文件2.5 编译目标配置.gn文件2.6 工程接口文件2.7 动态库编译.gn文件2.8 动态库源文件2.9 静态库编译.gn文件2.10 静态库源文件2.11 主程序编译.gn文件2.12 主程序源…...

STC定时器频率占空比程序

// // 一、宏定义区 // #include <STC15.H> //头文件 #include <intrins.h> //库函数文件 #define FOSC 12000000L //IRC频率 typedef …...

观察者 ➜ 事件总线:一路走来的碎碎念

写给未来的自己:每次手敲事件模型都要 Google,干脆把思路和踩坑一次性记清楚。文章很长,都是唠叨,目的是让自己看两眼就能把设计理由找回来。 目录 为什么我要折腾事件模型?V0 ─ 单一事件的观察者模式V1 ─ 多事件同步总线(类型拆分)V2 ─ 订阅者优先级(链式调用可控)…...