15 - Java 面向对象(高级)

抽象类

抽象类声明

abstract class 类名 { }

用关键字 abstract 修饰的类,就是抽象类

  • 抽象类使用abstract来修饰,抽象类不能实例化对象。
  • 抽象类中是可以写非静态的成员的,这时候这些非静态成员是可以继承给子类的。
  • 抽象类中是可以包含构造方法的。

抽象方法声明

用关键字 abstract 修饰的方法,就是抽象方法,抽象方法,只能够写在抽象类中。

public abstract 返回值类型 方法名(参数);

特点

  • 抽象方法:抽象方法使用 abstract 来修饰,只有声明,没有实现。
  • 结合抽象类和抽象方法:非抽象子类在继承一个抽象父类时,要实现父类中所有的抽象方法。
//研发工程师 
abstract class Developer {public abstract void work();//抽象函数。需要abstract修饰,并分号;结束
}//JavaEE工程师
class JavaEE extends Developer{public void work() {System.out.println("正在研发淘宝网站");}
}//移动端工程师
class Android extends Developer {public void work() {System.out.println("正在研发某款app");}
}

抽象类的特点

  • 抽象类与抽象方法都必须使用 abstract来修饰。
  • 抽象类不能直接创建对象。
  • 抽象类中可以有抽象方法,也可以没有抽象方法。
  • 抽象类的子类,实现了抽象方法的具体类或者抽象类。

接口

接口概念

接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”。

接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类来完成。这样将功能的定义与实现分离,优化了程序设计。

请记住:一切事物均有功能,即一切事物均有接口。

接口的特点

  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  • 接口中的方法访问权限修饰符都是public 。
  • 接口中的方法都是公有的。
  • 接口中的属性,默认的修饰符是 public static final 。
  • 接口中不能写构造方法 。

声明接口

Interface 关键字用来声明一个接口。

访问权限修饰符 interface 接口名 {

        抽象方法1;

        抽象方法2;

        抽象方法3;

}

接口的实现

接口不能实例化。

按照多态的方式,由具体的实现类实例化。其实这也是多态的一种,接口多态。

类使用 implements 关键字实现接口。在类声明中,Implements 关键字放在 class 声明后面。

public class XX extends YY implements ZZ { XX }

  • 一个非抽象类在实现接口后,需要实现接口中所有的抽象方法。
  • 一个类在继承自一个父类后,还可以再去实现接口。如果同时有父类和接口,那么继承父类在前,实现接口在后 。
  • 一个类可以实现多个接口。如果一个类实现的多个接口中有相同的方法,这个方法在实现类中只需要实现一次即可。
  • 接口之间是有继承关系的,而且接口之间的继承是多继承。
/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{public void eat(){System.out.println("Mammal eats");}public void travel(){System.out.println("Mammal travels");} public int noOfLegs(){return 0;}public static void main(String args[]){MammalInt m = new MammalInt();m.eat();m.travel();}
}

以上实例编译运行结果如下:

Mammal eats

Mammal travels

重写接口中声明的方法时,需要注意以下规则

  • 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
  • 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
  • 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

在实现接口的时候,也要注意一些规则

  • 一个类可以同时实现多个接口。
  • 一个类只能继承一个类,但是能实现多个接口。
  • 一个接口能继承另一个接口,这和类之间的继承比较相似。

接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。

下面的Sports接口被Hockey和Football接口继承:

// 文件名: Sports.javapublic interface Sports
{public void setHomeTeam(String name);public void setVisitingTeam(String name);
}// 文件名: Football.javapublic interface Football extends Sports
{public void homeTeamScored(int points);public void visitingTeamScored(int points);public void endOfQuarter(int quarter);
}// 文件名: Hockey.javapublic interface Hockey extends Sports
{public void homeGoalScored();public void visitingGoalScored();public void endOfPeriod(int period);public void overtimePeriod(int ot);
}

Hockey接口自己声明了四个方法,从Sports接口继承了两个方法,这样,实现Hockey接口的类需要实现六个方法。

相似的,实现Football接口的类需要实现五个方法,其中两个来自于Sports接口。

接口的多继承

在Java中,类的多继承是不合法,但接口允许多继承。

在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。 如下所示:

public interface Hockey extends Sports, Event

以上的程序片段是合法定义的子接口,与类不同的是,接口允许多继承,而 Sports及 Event 可以定义或是继承相同的方法

标记接口

最常用的标记接口是没有包含任何方法的接口。

标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。

标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

例如:java.awt.event 包中的 MouseListener 接口继承的 java.util.EventListener 接口定义如下:

package java.util;

public interface EventListener {}

没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的

  • 建立一个公共的父接口:

正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

  • 向一个类添加数据类型:

这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

内部类

什么是内部类?

  • 在Java中,可以将一个类的定义放在另外一个类的定义内部,这就是内部类。内部类本身就是类的一个属性,与其他属性定义方式一致。

内部类的分类

静态内部类
  • 定义在类内部的静态类,就是静态内部类。
public class Outer {private static int radius = 1;static class StaticInner {public void visit() {System.out.println("visit outer static  variable:" + radius);}}
}
  • 静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,

new 外部类.静态内部类(),如下:

Outer.StaticInner inner = new Outer.StaticInner();

inner.visit();

成员内部类
  • 定义在类内部,成员位置上的非静态类,就是成员内部类。
public class Outer {private static  int radius = 1;private int count =2;class Inner {public void visit() {System.out.println("visit outer static  variable:" + radius);System.out.println("visit outer   variable:" + count);}}
}
  • 成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类(),如下:

Outer outer = new Outer();

Outer.Inner inner = outer.new Inner();

inner.visit();

局部内部类
  • 定义在方法中的内部类,就是局部内部类。
public class Outer {private  int out_a = 1;private static int STATIC_b = 2;public void testFunctionClass(){int inner_c =3;class Inner {private void fun(){System.out.println(out_a);System.out.println(STATIC_b);System.out.println(inner_c);}}Inner  inner = new Inner();inner.fun();}public static void testStaticFunctionClass(){int d =3;class Inner {private void fun(){// System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量System.out.println(STATIC_b);System.out.println(d);}}Inner  inner = new Inner();inner.fun();}
}
  • 定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类(),如下:
 public static void testStaticFunctionClass(){class Inner {}Inner  inner = new Inner();}
匿名内部类
  • 匿名内部类就是没有名字的内部类,日常开发中使用的比较多。
public class Outer {private void test(final int i) {new Service() {public void method() {for (int j = 0; j < i; j++) {System.out.println("匿名内部类" );}}}.method();}}//匿名内部类必须继承或实现一个已有的接口 interface Service{void method();
}
  • 除了没有名字,匿名内部类还有以下特点:
    • 匿名内部类必须继承一个抽象类或者实现一个接口。
    • 匿名内部类不能定义任何静态成员和静态方法。
    • 当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
    • 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
  • 匿名内部类创建方式:

new 类/接口{ //匿名内部类实现部分 }

内部类的优点

我们为什么要使用内部类呢?因为它有以下优点:

  • 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
  • 内部类不为同一包的其他类所见,具有很好的封装性;
  • 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
  • 匿名内部类可以很方便的定义回调。

内部类有哪些应用场景

  1. 一些多算法场合
  2. 解决一些非面向对象的语句块。
  3. 适当使用内部类,使得代码更加灵活和富有扩展性。
  4. 当某个类除了它的外部类,不再被其他的类使用时。
局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?

先看这段代码:

 public class Outer {void outMethod(){final int a =10;class Inner {void innerMethod(){System.out.println(a);}}}
}

以上例子,为什么要加final呢?是因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。

内部类变量

public class Outer {private int age = 12;class Inner {private int age = 13;public void print() {int age = 14;System.out.println("局部变量:" + age);System.out.println("内部类变量:" + this.age);System.out.println("外部类变量:" + Outer.this.age);}}public static void main(String[] args) {Outer.Inner in = new Outer().new Inner();in.print();}}

运行结果:

局部变量:14

内部类变量:13

外部类变量:12

枚举类

枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一年的 12 个月份,一个星期的 7 天,方向有东南西北等。

Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。

实现步骤

  1. 构造器私有化
  2. 本类内部创建一组对象
  3. 对外暴露对象(通过为对象添加public final static修饰符)
  4. 提供get方法,但是不提供set方法

注意事项和细节

  1. 不需要提供setxxx 方法,因为枚举对象值通常为只读
  2. 枚举对象/属性使用 final + static 共同修饰,实现底层优化
  3. 枚举对象名通常使用全部大写,常量的命名规范
  4. 枚举对象根据需要,也可以有多个属性

例如定义一个颜色的枚举类。

enum Color {

        RED, GREEN, BLUE;

}

以上枚举类 Color 颜色常量有 RED, GREEN, BLUE,分别表示红色,绿色,蓝色。

使用实例:

enum Color
{RED, GREEN, BLUE;
}public class Test
{// 执行输出结果public static void main(String[] args){Color c1 = Color.RED;System.out.println(c1);}
}

执行以上代码输出结果为:

RED

内部类中使用枚举

枚举类也可以声明在内部类中:

public class Test
{enum Color{RED, GREEN, BLUE;}// 执行输出结果public static void main(String[] args){Color c1 = Color.RED;System.out.println(c1);}
}

执行以上代码输出结果为:

RED

每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。

以下的枚举类 Color 转化在内部类实现:

class Color
{public static final Color RED = new Color();public static final Color BLUE = new Color();public static final Color GREEN = new Color();
}

迭代枚举元素

可以使用 for 语句来迭代枚举元素:

enum Color
{RED, GREEN, BLUE;
}
public class MyClass {public static void main(String[] args) {for (Color myVar : Color.values()) {System.out.println(myVar);}}
}

执行以上代码输出结果为:

RED

GREEN

BLUE

在 switch 中使用枚举类

枚举类常应用于 switch 语句中:

enum Color
{RED, GREEN, BLUE;
}
public class MyClass {public static void main(String[] args) {Color myVar = Color.BLUE;switch(myVar) {case RED:System.out.println("红色");break;case GREEN:System.out.println("绿色");break;case BLUE:System.out.println("蓝色");break;}}
}

执行以上代码输出结果为:

蓝色

枚举类成员

枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。

枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。

enum Color
{RED, GREEN, BLUE;// 构造函数private Color(){System.out.println("Constructor called for : " + this.toString());}public void colorInfo(){System.out.println("Universal Color");}
}public class Test
{    // 输出public static void main(String[] args){Color c1 = Color.RED;System.out.println(c1);c1.colorInfo();}
}

执行以上代码输出结果为:

Constructor called for : RED

Constructor called for : GREEN

Constructor called for : BLUE

RED

Universal Color

接口与类

接口与类相似点

  • 一个接口可以有多个方法。
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多继承。

访问权限修饰符

  • 和类一样,只能有 public 和默认的default权限。
  • 接口不是类,不能实例化对象。
  • 接口,暂时和类写成平级的关系。
  • 接口名字是一个标识符,遵循大驼峰命名法

抽象类与接口比较

  • 抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。
  • 从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
  • 接口的设计是自上而下的。
  • 抽象类的设计是自下而上的。

相同点

  • 接口和抽象类都不能实例化
  • 都位于继承的顶端,用于被其他实现或继承
  • 都包含抽象方法,其子类都必须覆写这些抽象方法

不同点

参数

抽象类

接口

声明

抽象类使用 abstract 关键字声明

接口使用 interface 关键字声明

实现

子类使用 extends 关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现

子类使用 implements 关键字来实现接口。它需要提供接口中所有声明的方法的实现

构造器

抽象类可以有构造器

接口不能有构造器

访问修饰符

抽象类中的方法可以是任意访问修饰符

接口方法默认修饰符是 public。并且不允许定义为 private 或者 protected

多继承

一个类最多只能继承一个抽象类

一个类可以实现多个接口

字段声明

抽象类的字段声明可以是任意的

接口的字段默认都是 static 和 final 的

备注:

  • JDK 1.8 以后,接口里可以有静态(static)方法和方法体了。
  • JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。
  • JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。
  • JDK 14 以后,引入sealed 接口(仅在某些子类中使用),进一步增强接口的功能。

现在,我们可以为接口提供默认实现的方法了,并且不用强制子类来实现它。

  • 接口和抽象类各有优缺点,在接口和抽象类的选择上,必须遵守这样一个原则:
    • 行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
    • 选择抽象类的时候通常是需要定义子类的行为,又要为子类提供通用的功能。

 类、抽象类、接口

三者比较

  • 类与类:继承关系,只能单继承,但是可以多层继承(生物-》动物=》猫类)。
  • 类与接口:实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口。
  • 接口与接口:继承关系,可以单继承,也可以多继承。

三者区别

  • 成员区别
    • 抽象类:变量、常量、有抽象方法、抽象方法、非抽象方法
    • 接口:常量、抽象方法
    • 类:变量、常量、方法
  • 关系区别
    • 类与类:单继承
    • 类与接口:单实现、多实现
    • 接口与接口:单继承、多继承
  • 设计理念区别
    • 接口的设计是自上而下的。
    • 抽象类的设计是自下而上的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python源码实例游戏开发小程序办公自动化网络爬虫项目开发源码(250+个项目、26.6GB)

文章目录 源代码下载地址项目介绍预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 python源码实例游戏开发小程序办公自动化网络爬虫项目开发源码(250个项目、26.6GB) 预览 项目备注 1、该资源内项目代码都经过测试运行成功&#xff0c;功能ok的情…

VINS_MONO视觉导航算法【三】ROS基础知识介绍

文章目录 其他文章说明ROSlaunch文件基本概念定义用途 文件结构根标签常用标签\<node>\<param>\<rosparam>\<remap>\<include>\<arg>\<group> 示例基本示例嵌套示例 使用方法启动 *.launch 文件传递参数 总结 ROS topicTopic 的基本…

MySql:理解数据库

目录 一、什么是数据库 第一层理解 第二层理解 第三层理解 二、Linux下的数据库 三、基本认识 登录数据库时&#xff0c; mysql -u root -h 127.0.0.1 -P 3306 -p -h指定MySql服务器所在主机&#xff0c;若在本地则为回环地址。-P表示目标主机上MySql服务端口号 一般简单…

BERT模型的输出格式探究以及提取出BERT 模型的CLS表示,last_hidden_state[:, 0, :]用于提取每个句子的CLS向量表示

说在前面 最近使用自己的数据集对bert-base-uncased进行了二次预训练&#xff0c;只使用了MLM任务&#xff0c;发现在加载训练好的模型进行输出CLS表示用于下游任务时&#xff0c;同一个句子的输出CLS表示都不一样&#xff0c;并且控制台输出以下警告信息。说是没有这些权重。…

高级java每日一道面试题-2024年12月03日-JVM篇-什么是Stop The World? 什么是OopMap? 什么是安全点?

如果有遗漏,评论区告诉我进行补充 面试官: 什么是Stop The World? 什么是OopMap? 什么是安全点? 我回答: 在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;Stop The World、OopMap 和 安全点 是与垃圾回收&#xff08;GC&#xff09;和性能优化密切相关的概念。理…

PROTEUS资源导引

本专栏讲述51、32单片机的仿真设计&#xff0c;且所有文章资源共享&#xff0c;如需哪篇文章&#xff0c;可按ctrlF键搜索查询&#xff0c;点击进入即可。 -----------------------------------------------------------目录------------------------------------------------…

Vue框架开发一个简单的购物车(Vue.js)

让我们利用所学知识来开发一个简单的购物车 &#xff08;记得暴露属性和方法&#xff01;&#xff01;&#xff01;&#xff09; 首先来看一下最基本的一个html框架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

系统加固-Linux不允许用户使用密码登录,只能使用密钥登录

一、密码登录的安全隐患 传统的密码登录方式&#xff0c;尽管简单直接&#xff0c;却存在诸多安全隐患。首先&#xff0c;密码本身容易被猜测或通过暴力破解手段获得。特别是当用户设置了过于简单或常见的密码时&#xff0c;系统面临的安全风险将显著增加。其次&#xff0c;密…

大数据实验E5HBase:安装配置,shell 命令和Java API使用

实验目的 熟悉HBase操作常用的shell 命令和Java API使用&#xff1b; 实验要求 掌握HBase的基本操作命令和函数接口的使用&#xff1b; 实验平台 操作系统&#xff1a;Linux&#xff08;建议Ubuntu16.04或者CentOS 7 以上&#xff09;&#xff1b;Hadoop版本&#xff1a;3…

【Vivado】xdc约束文件编写

随手记录一下项目中学到的约束文件编写技巧。 时序约束 创建生成时钟 参考链接&#xff1a; Vivado Design Suite Tcl Command Reference Guide (UG835) Vivado Design Suite User Guide: Using Constraints (UG903) 通过Clocking Wizard IP创建的时钟&#xff08;MMCM或…

Electron + Vue 简单实现窗口程序(Windows)从零到一

前言 想做一个桌面应用程序&#xff0c;一直没有找到简单快速可上手的框架。刚好有点前端的底子&#xff0c;就发现了Electron。关于Electron的介绍&#xff0c;请移步 https://www.electronjs.org/ 查阅。 简单来说&#xff0c;引用官网的话&#xff0c;Electron是一个使用 …

spring boot整合ArtemisMQ进行手动消息确认

1、SpringBoot整合ArtemisMQ进行手动消息确认使用的是&#xff1a; factory.setSessionTransacted(false); factory.setSessionAcknowledgeMode(ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE); 2、SpringBoot整合ActiveMQ进行手动消息确认使用的是&#xff1a; factory.setSe…

健康养生生活

在快节奏的现代生活中&#xff0c;健康养生愈发成为人们关注的焦点。它不仅是一种生活方式&#xff0c;更是对生命质量的珍视与呵护。 健康养生&#xff0c;饮食为先。合理的膳食结构是维持身体健康的基石。我们应确保每餐营养均衡&#xff0c;增加蔬菜、水果、全谷物以及优质蛋…

开源模型应用落地-安全合规篇-用户输入价值观判断(三)

一、前言 在深度合规功能中,对用户输入内容的价值观判断具有重要意义。这一功能不仅仅是对信息合法性和合规性的简单审核,更是对信息背后隐含的伦理道德和社会责任的深刻洞察。通过对价值观的判断,系统能够识别可能引发不当影响或冲突的内容,从而为用户提供更安全、更和谐的…

如何避免数据丢失:服务器恢复与预防策略

在当今数字时代&#xff0c;数据对于个人和企业来说都至关重要。数据丢失可能会导致严重的财务损失、业务中断甚至法律责任。因此&#xff0c;采取措施防止数据丢失至关重要。本文将讨论服务器数据丢失的常见原因以及如何防止数据丢失的有效策略。 服务器数据丢失的常见原因 服…

LeetCode Hot100 11~20

目录 子串11. 滑动窗口最大值12. 最小覆盖子串 数组13. 最大子数组和14. 合并区间15. 翻转数组16. 除数字自身以外的乘积17. 缺失的第一个正数 矩阵18. 矩阵置零19. 螺旋矩阵20 旋转图像90度 子串 11. 滑动窗口最大值 本题使用deque来维护一个单调队列 注意删除元素和添加元素…

网站访问统计A/B测试与数据分析

在网站运营中&#xff0c;访问统计和数据分析是优化用户体验和提高转化率的关键工具。A/B测试作为一种数据驱动的方法&#xff0c;能够帮助网站运营者验证设计和内容的有效性。A/B测试的基本原理是同时展示两个不同的版本&#xff08;A和B&#xff09;&#xff0c;通过比较它们…

Spring MVC:深入理解与应用实践

前言 Spring MVC是Spring框架提供的一个用于构建Web应用程序的Model-View-Controller&#xff08;MVC&#xff09;实现。它通过分离业务逻辑、数据、显示来组织代码&#xff0c;使得Web应用程序的开发变得更加简洁和高效。本文将从概述、功能点、背景、业务点、底层原理等多个…

C学习:移位幻影之左移一个负数,会发生什么?

C学习&#xff1a;移位幻影之左移一个负数&#xff0c;会发生什么&#xff1f; 问题背景无符号数移位问题有符号数移位操作使低位置零问题 问题背景 C语言中&#xff0c;移位是个简单的问题&#xff0c;但又是个高风险的问题。 简单在于&#xff0c;大部分场景都可以理解为乘或…

芯驰X9SP与汽车麦克风-打造无缝驾驶体验

当今汽车技术的进步不仅提升了驾驶体验&#xff0c;还改变了我们与车辆互动的方式。汽车麦克风作为车内语音控制系统的重要组成部分&#xff0c;正逐渐成为现代汽车的标配。 技术原理 汽车麦克风主要依赖于声音传感技术&#xff0c;通常包括电容式麦克风和动圈式麦克风。这些…