类和对象(5)——抽象类和接口

目录

1. 抽象类

1.1 抽象类的概念

1.2 抽象类语法:abstract关键字

1.3 抽象类的特性

1.4 抽象类的作用

2. 接口

2.1 接口的概念

2.2 接口语法:interface关键字

2.3 接口的实现:implements关键字

2.4 接口的特性

2.5 实现多个接口

2.6 接口间的继承

2.7 接口的多态性

2.8 再谈instanceof

2.8.1 检查接口的实现

2.8.2 类型可见性问题

2.8.3 易混淆的可见性

3. 抽象类与接口的区别


1. 抽象类

1.1 抽象类的概念

在面向对象的概念中,所有的对象都是通过类来描绘的;但是反过来,并不是所有的类都是用来描绘对象的,如果 一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

  • 抽象类是一种不能被实例化,只能用作其他类的父类的类。它通常用于定义一组具有共同特征和行为的子类的基础框架,这些共同特征和行为以抽象方法的形式呈现,子类需要提供这些抽象方法的具体实现。

1.2 抽象类语法:abstract关键字

那么在java语言中,抽象类要如何表示呢?

java提供了一个abstract关键字,被该关键字修饰的类就是抽象类。

抽象类的语法:

(其他修饰词)  abstract  class 抽象类名{

        ……

}

abstract除了可以修饰类,还可以修饰成员方法使其成为抽象方法。需要注意的是,抽象方法只能存在于抽象类当中

抽象方法的语法:

(其他修饰词)  abstract  class 抽象类名{

        ……

        (其他修饰词)  abstract  返回值类型  抽象方法名 (参数表);   //抽象方法无具体实现

        ……

}

例如:

public abstract class Animal {private String name;private int age;//抽象方法abstract public void eat();
}

1.3 抽象类的特性

抽象类具有很多的特性和使用要求,我在下面一一列举出来。

1. 抽象类不能被直接实例化成对象。

以上面抽象类Animal为例:

其实这样的要求也很好理解,因为抽象类的产生就不是为了描述对象的,它也没有包含足够的信息来描绘一个具体的对象,必须由它的非抽象子类来实例化对象。


2. 抽象类被继承后,其子类要重写父类中的抽象方法否则子类也必须设为抽象类,被abstract修饰。

子类Dog没有重写抽象方法,且没有设为抽象类而报错:

package demo3;    //包名:demo3
//抽象父类Animal
public abstract class Animal {public String name;public int age;//抽象方法abstract public void eat();
}
//Dog类继承自抽象类
public class Dog extends Animal{public void bark(){System.out.println(name+"在汪汪叫");}
}

补充:非抽象子类需要重写的抽象方法都来自其直接父类的抽象方法

假如有A、B、C三个类,A是B的直接父类,B是C的直接父类;A和B都是抽象类,C是普通类。如果B重写了A中的部分抽象方法,那么C要重写的抽象方法有 A剩下的抽象方法 B新增加的抽象方法

例如:

​//抽象类Animal
public abstract class Animal {public String name;//2个抽象方法abstract public void eat();abstract public void sleep();
}
//抽象类Dog
public abstract class Dog extends Animal{//重写了抽象方法eat()public void eat(){System.out.println(name+"在吃狗粮");}//新增1个抽象方法walk()abstract public void walk();
}
//普通类 柯基
public class Corgi extends Dog{//报错:没有重写抽象方法sleep()和walk()
}

这里Dog继承自Animal,所以Dog包含成员变量name、父类方法eat和sleep 以及自己新增的抽象方法walk。

又因为Dog重写了抽象方法eat,eat方法在Dog类已经不是抽象方法,所以Dog类中只有sleep和walk两个抽象方法。

由于非抽象子类需要重写的抽象方法都来自其直接父类的抽象方法,所以柯基Corgi类必须要重写sleep和walk这两个直接来自Dog类的抽象方法。


3. 抽象方法不能被private、final和static修饰,因为抽象方法要被子类重写。


4. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量。


5. 抽象类中不一定有抽象方法,但是抽象方法只能存在于抽象类当中

无抽象方法的抽象类:

报错·含抽象方法的普通类:

1.4 抽象类的作用

抽象类本身不能被实例化,要想使用,只能创建该抽象类的子类。 然后让子类重写抽象类中的抽象方法。

有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?

确实如此. 但是使用抽象类相当于多了一重编译器的校验.

使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类 了, 使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.

很多语法存在的意义都是为了 "预防出错", 例如我们曾经用过的 final 也是类似. 创建的变量用户不去修改, 不 就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候, 让编译器及时提醒我们. 充分利用编译器的校验, 在实际开发中是非常有意义的

2. 接口

2.1 接口的概念

在现实生活中,接口的例子比比皆是,比如:笔记本上的USB口,电源插座等。

电脑侧面的USB口上,可以插:U盘、鼠标、键盘...所有符合USB协议的设备

电源插座的插孔上,可以插:电脑、电视机、电饭煲...所有符合规范的设备

通过上述例子可以看出:接口就是公共的行为规范标准。大家在实现时,只要符合规范标准,就可以通用

我们知道,在编程上我们用类来描述对象,像电脑、鼠标、U盘这些对象都可以用类来描述。自然的,我们也会有编程上的接口。

在Java中,接口可以看成是多个类的公共规范,也是一种引用数据类型。

2.2 接口语法:interface关键字

接口的语法格式 与 类的语法格式类似,将 class关键字 换成 interface关键字,就定义了一个接口。

接口的语法格式:

(其他限定词)  interface  接口名{

        ……

}

例如:写一个图形接口,规范是要实现画图形方法draw。

public interface IShape {void draw();    //画一个图形
}

注意:

  • 接口的命名采用大驼峰命名法。
  • 接口的命名一般以大写字母 I 开头,它的后一个字母也要大写。

2.3 接口的实现:implements关键字

接口不能直接使用,必须要有一个"实现类"来"实现"该接口。而实现指的是:重写接口中的所有抽象方法。(在接口中定义的方法都是抽象方法)

在java中,提供一个关键字implements来让我们完成对接口的实现

实现的语法:

(其他限定词) class 类名 implements 接口名{

        ……

        //重写的接口方法

}

例如:

//接口
public interface IShape {void draw();    //画一个图形
}//实现类
public class Flower implements IShape{@Overridepublic void draw() {System.out.println("画一朵花……");}
}//测试
public class Test {public static void main(String[] args) {IShape iShape = new Flower();//向上转型iShape.draw();}
}

可以看到,实现了接口,可以通过向上转型的方式来调用接口函数,这是接口多态性的一种体现。

2.4 接口的特性

1. 与抽象类一样,接口虽是一种引用类型,但是不能直接new接口的对象

例如:


2. 接口中的成员变量都是被“ public static final ”修饰的。

也就是说,接口中的成员变量是一种静态全局常量。无论是无修饰(default),还是显式用public修饰、static修饰或final修饰,它们最终都是由“ public static final共同修饰

以下面的USB接口为例:

public interface USB {double brand = 10;
}


3. 接口中的方法都是由“ public abstract ”修饰。

无论是无修饰(default),还是显式用public修饰或abstract修饰,接口方法都是由public abstract共同修饰。也就是说接口方法都是公共的抽象方法,必须要求实现类进行方法重写,这体现了接口作为公共规范的作用

例如:

// 接口IShape

// Flower类

Flower类没有重写IShape接口的draw方法,由于接口方法都是抽象的,所以会报错。

补充:如果实现类没有重写接口的所有抽象方法,那么该实现类要设为抽象类


4. 由于接口的变量和方法都有固定的修饰符修饰,所以不能用其他修饰符 修饰接口的变量和方法。(比如private、protected)

错误例子:

补充:接口的变量和方法都有默认修饰符,一般建议接口的变量和方法前面都不写任何修饰符


5. 接口中不能有静态代码块动态代码块构造方法

静态代码块一般用来初始化静态变量,动态代码块和构造方法一般用来初始化成员变量,但是接口中的变量都是常量,不能修改。

错误例子:

public interface USB {int BRAND = 10;static {//静态代码块}{//实例代码块}USB(int brand){BRAND = brand;}
}


6. 实现类重写接口方法时,重写的方法的包访问权限不能比接口方法的权限要低。即:不能是无修饰词(default)、不能是protected、不能是private

例如:

【补充:其实 实现类的重写方法的访问权限在一种情况可以是无修饰词(default)的,这种情况我在第8点说】


7(小知识). 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class


8(拓展). 从Java8版本开始,接口中可以定义default方法(默认方法)。它允许在接口中为方法提供默认的实现。

default方法在接口中的定义方式:

  • 显示使用default关键字:在接口的方法签名前使用default关键字来定义一个默认方法。例如,default void methodName() {...}
  • 包含方法体:与接口中的抽象方法不同,默认方法是具体的方法实现,需要在接口中给出方法的具体代码逻辑

【注意】: 接口方法被default修饰后,就不能再被final和static修饰。

例如:

//图形·接口
public interface IShape {//抽象方法void draw1();//默认方法default  void draw2(){System.out.println("画两次图形");}
}
//圆形·类 :只重写抽象方法
public class Circle implements IShape{@Overridepublic void draw1() {System.out.println("画一个圆……");}
}
//花形·类:抽象方法和默认方法都重写了
public class Flower implements IShape{@Overridepublic void draw1() {System.out.println("画一朵花……");}@Overridepublic void draw2() {System.out.println("画两朵花");}
}public class Test {public static void main(String[] args) {Circle circle = new Circle();circle.draw1();circle.draw2();    //会使用接口的默认方法System.out.println("============================");Flower flower = new Flower();flower.draw1();flower.draw2();}
}

【这里的第8点特性属于拓展内容,了解即可】


2.5 实现多个接口

java中没有多继承,即一个子类不能继承自多个父类,但是一个类可以实现多个接口。

语法格式:(所有的接口都跟在implements的后面,每个接口之间用逗号隔开)

【无继承】

  class 实现类 implements 接口1,接口2,……,接口K{

          ……  //实现类的成员

  }

【有继承】(只能有一个父类) (“继承extends”要在“实现implements”前面)

  class 实现类 extends 父类名称 implements 接口1,接口2,……,接口K{

          ……  //实现类的成员

  }

下面演示如何用接口和继承来表示企鹅类:

先有父类Animal:

abstract public class Animal {protected String name;public Animal(String name){this.name = name;}
}

另外我们再提供一组接口, 分别表示 "会飞的", "会跑的", "会游泳的":

 interface IFlying {void fly();}interface IRunning {void run();}interface ISwimming {void swim();}

最后我们创建具体的动物——企鹅类(企鹅既能在路上走,也能在水中游

public class Penguin extends Animal implements IRunning,ISwimming{public Penguin(String name) {super(name);}@Overridepublic void run() {System.out.println(name+"用两只脚走路");}@Overridepublic void swim() {System.out.println(name+"用两只翅膀游泳");}
}

tips:在IDEA中使用 ctrl + i 可快速实现接口。

2.6 接口间的继承

类与类之间可以有继承关系,那接口与接口之间可以有继承关系吗?

接口与接口之间可以有继承关系,而且接口可以多继承,即一个接口可以继承自多个接口。

语法格式:(继承语法是extends,每个父接口之间用逗号隔开)

interface 子接口 extends 父接口1,父接口2,……,父接口k{

        ……

}

青蛙是两栖动物,我们用接口间的继承可以这样表示:

interface IRunning {void run();}interface ISwimming {void swim();}// 两栖的动物:既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {}class Frog implements IAmphibious {...}

2.7 接口的多态性

当实现类实现了接口,那么它就可以向接口类型进行向上转型。这体现了接口的多态性。

接口不仅仅是一种规范标准,它还是一种引用类型,这样的设计提高了代码的可重复性。

【实现多个接口】

实现类实现了多个接口,那么被实现的接口都可以接收实现类的向上转型。

例如:

//接口
public interface ISwimming {void swim();
}public interface IRunning {void run();
}
//实现类
public class Penguin implements ISwimming,IRunning{@Overridepublic void swim() {System.out.println("企鹅游泳");}@Overridepublic void run() {System.out.println("企鹅走路");}
}public class Dog implements IRunning{@Overridepublic void run() {System.out.println("狗在奔跑");}
}//多态方法
public class Test {public static void swim(ISwimming iSwimming){   //ISwimming接口类型作为多态类型参数iSwimming.swim();   //方法会根据动态绑定来使用}public static void run(IRunning iRunning){      //IRunning接口类型作为多态类型参数iRunning.run();}public static void main(String[] args) {Penguin penguin = new Penguin();swim(penguin);     //向上转型传参run(penguin);System.out.println("==============");Dog dog = new Dog();run(dog);}
}

这里的Penguin类实现了ISwimming接口和IRunning接口,所以swim方法和run方法可以完成对penguin的向上转型。


【接口间的继承】

如果子接口继承自父接口,而实现类“直接实现”的是子接口,那么父接口也可以接收实现类的向上转型

例如:

//IAmphibious接口继承自上面的ISwimming、IRunning接口
public interface IAmphibious extends ISwimming,IRunning{}//Penguin类直接实现IAmphibious接口
public class Penguin implements IAmphibious{@Overridepublic void swim() {System.out.println("企鹅游泳");}@Overridepublic void run() {System.out.println("企鹅走路");}
}public class Test {public static void swim(ISwimming iSwimming){   //ISwimming接口类型作为多态类型参数iSwimming.swim();   }public static void run(IRunning iRunning){      //IRunning接口类型作为多态类型参数iRunning.run();}public static void main(String[] args) {Penguin penguin = new Penguin();swim(penguin);     run(penguin);}
}

  • Penguin类实现了Imphibious接口,所以Penguin可以向Imphibious转型。
  • 而Imphibious继承自ISwimming接口和IRunning接口,所以Imphibious可以向ISwimming接口和IRunning接口转型。
  • 于是乎Penguin可以向ISwimming接口和IRunning接口向上转型

【注意】

如果子接口继承自父接口,实现类直接实现的也是这个父接口,那么该实现类不能向子接口进行向上转型。

错误例子:

//父接口
public interface IRunning {void run();
}//子接口:表示爬行类的动物
public interface ICreeping extends IRunning{
}//实现类:蜥蜴
public class Lizard implements IRunning{@Overridepublic void run() {System.out.println("蜥蜴在快速爬行");}
}//用子接口ICreeping接收实现类Lizard
public class Test {public static void run(ICreeping iCreeping){      iCreeping.run();}public static void main(String[] args) {Lizard lizard = new Lizard();run(lizard);        //报错:Lizard类型与ICreeping类型不兼容}
}


接口多态性与继承多态性的对比:

2.8 再谈instanceof

2.8.1 检查接口的实现

我在《类和对象(4)——多态》中讲解过instanceof关键字,当时说过“该关键字不仅能判断类,还能判断接口”。但当时还没学到接口,现在让我们看看instanceof对于接口的作用。

instanceof的作用:(对象  instanceof  类名/接口名)

  • 对于类:检查对象是否指定类型的实例,或该类型的子类实例
  • 对于接口:检查对象是否实现了指定接口,或该接口的父接口

为什么instanceof检查类的时候,可以检查其子类,而在检查接口的时候,却是可以检查其父接口呢?

这就不得不说一下instanceof检查的实际用途了:

类和instanceof的用途:确保向下转型的安全,从而让子类实例变量接收向下转型后的父类实例变量,使用子类特有的功能

接口和instanceof的用途:确保对象具有某类多态行为,从而调用该多态方法

类的举例和解析:

abstract public class Animal {public String name;public Animal(String name){this.name = name;}
}public class Dog extends Animal{public Dog(String name) {super(name);}public void eat(){System.out.println(super.name+"在吃狗粮");}
}public class Corge extends Dog{public Corge(String name) {super(name);}public void eat(){System.out.println(name+"在吃科技合成肉");}
}public class Test {public static void main(String[] args) {Animal animal1 = new Dog("小狗");if (animal1 instanceof Dog){    //检查为Dog类的实例Dog dog = (Dog) animal1;dog.eat();}Animal animal2 = new Corge("小柯基");if(animal2 instanceof Dog){     //检查为Dog类的子类实例Dog dog = (Dog) animal2;dog.eat();}}
}

  • Dog类和Corge类都有自己特有的eat方法
  • 在animal1中,由于对象的本质是Dog类的实例,故可以安全地将animal1向下转型成Dog类
  • 在animal2中,虽然对象的本质是Corge类的实例,但由于Corge类是Dog类的子类(即Corge类可以向上转型成Dog类),所以它也可以安全地将animal2向下转型成Dog类
  • 这就解释了:为什么instanceof能检查指定类型的子类

接口的举例和解析:

//父接口
public interface IRunning {void run();
}
public interface ISwimming {void swim();
}//子接口
public interface IAmphibious extends ISwimming,IRunning{}//实现类
public class Penguin extends Animal implements IAmphibious{@Overridepublic void swim() {System.out.println("企鹅游泳");}@Overridepublic void run() {System.out.println("企鹅走路");}
}//多态方法
public class Test {public static void run(IRunning iRunning){iRunning.run();}public static void main(String[] args) {Animal animal = new Penguin();  //向上转型if(animal instanceof IAmphibious){   检查到指定接口的父接口的run行为run( (IAmphibious)animal );         //此时调用的是Test类中的多态方法run//或写成((IAmphibious)animal).run();  此时调用的是自己的重写方法run}if(animal instanceof IRunning){      检查指定接口run((IRunning) animal);//或写成((IRunning)animal).run();}}
}

  • 子接口继承自多个父接口,实现类直接实现子接口 就相当于是 把所有父接口的行为都实现了一遍,那自然可以使用 以父接口类型为参数类型的多态方法
  • 这解释了:为什么instanceof能检查指定接口的父接口

小结:


2.8.2 类型可见性问题

如果我们将上面接口例子中Test类(含多态方法的那个)修改成下面这样会发生什么:

可以发现,我们把强制类型转换用的“(IAmphibious)”去掉后居然报错了。这是编译时类型对成员可见性的限制惹的祸。


要明白 “编译时类型对成员可见性的限制”,我们必需先了解编译时类型和运行时类型的概念。

编译时类型(也称 声明类型)

  • 变量在代码中声明的类型。(如" Parent parent;",此时实例变量parent的数据类型Parent就是编译时类型)(编译时类型也包括基础类型,如int、double)
  • 编译器仅根据此类型检查可访问的成员变量和方法。

运行时类型(也称 实际类型)

  • 对象实际所属的类型。(如“ new Child() ”)
  • 运行时动态决定,但编译时不可见

当用编译时类型的变量 访问 运行时类型的特有成员时,编译器检查发现该声明类型不具有访问特有成员的能力,直接触发了编译错误。这就是编译时类型对可见性的限制

  1. 强制转换的作用
    强制转换的本质是 告诉编译器,请按强转类型检查成员。编译器接受新的编译时类型,从而允许访问该类型定义的成员。

  2. 运行时验证
    强制转换可能在运行时失败(如 强转类型 与 对象实际类型 不符),因此需配合 instanceof 提前检查类型安全。


2.8.3 易混淆的可见性

上述发生的编译错误属于类型可见性的问题,而不是权限的问题。

成员可见性:

  • 在java中,权限指的就是各种访问修饰符
  • 成员可见性的控制机制是访问修饰符(比如public、protected),为每个成员变量和方法赋予权限。


类可见性:

  • 类可见性的控制机制也是访问修饰符,为类赋予访问权限。
  • 成员可见性是 成员变量和成员方法 被访问修饰符修饰,共有4种权限类可见性 被访问修饰符修饰,顶级类只有public类或默认类(default)2种
  • 类的可见性成员可见性的 前提。(如果顶级类是默认类,且内部所有成员都是public修饰的,那么不是同一个包的类就无法访问该顶级类及其所有成员。)

错误例子:

在包test1中有默认类Demo:

当我们在包test2中尝试使用Demo会报错:


包可见性:

  • 包可见性 = default 权限 = 包访问权限 = 仅包内可见。
  • 包可见性 包含于 成员可见性和类可见性当中。(包可见性是权限中的一种具体类型)

成员可见性和类的可见性通过访问修饰符定义,具体规则如下:


最终总结:

  1. 类可见性 和 成员可见性属于访问权限控制的同一维度(层级不同),且 类可见性是成员可见性的前提

  2. 包可见性是访问权限控制中的一种具体类型(默认修饰符),属于成员可见性和类可见性的一部分。

  3. 类型可见性是独立于访问控制的另一维度,属于编译时类型系统的限制。

3. 抽象类与接口的区别

核心区别: 抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用(不必重写),而接口中不能包含普通方法(但是可以包含default方法),子类必须重写所有的抽象方法。

下面的表格是抽象类和接口不同的地方:

抽象类和接口的相同之处:

  1. 可以没有任何成员。(此时的接口被称作空接口或标记接口)
  2. 抽象方法不能被private、static、final修饰。
  3. 子类/实现类 重写方法的包访问权限不能更低。
  4. 子类/实现类 没有重写完所有的抽象方法时,必须设置为抽象类。
  5. 字节码文件的后缀都是.class。

本期分享完毕,感谢大家的支持Thanks♪(・ω・)ノ

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

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

相关文章

利用租用的GPU进行训练

对于大模型的微调以及推理,对显卡的要求较高,我们就可以通过租一台来进行训练,这里我租用的是:AutoDL算力云 | 弹性、好用、省钱。租GPU就上AutoDL 推荐博客:新手小白如何租用GPU云服务器跑深度学习_gpu租用-CSDN博客…

[操作系统] 基础IO:系统文件I/O

在 Linux 操作系统中,文件 I/O(输入/输出)是程序与文件系统交互的基础。理解文件 I/O 的工作原理对于编写高效、可靠的程序至关重要。本文将深入探讨系统文件 I/O 的机制。 一种传递标志位的方法 在 Linux 中,文件的打开操作通常…

Qt MainWindow

文章目录 0. 概述1. 菜单栏 QMenuBar1.1 例子1,使用图形化界面1.2 例子2,使用代码创建1.3 例子3,添加快捷键1.4 例子4,添加子菜单1.5 例子5,添加分割线和图标1.6 内存泄漏问题 2. 工具栏 QToolBar2.1 例子1&#xff0c…

阅读论文“用于车联网安全车载通信的机器学习技术“的学习笔记

前言 论文全称为Machine Learning Technologies for Secure Vehicular Communication in Internet of Vehicles: Recent Advancesc and Applications 智能交通系统(ITS)和计算系统的快速发展为智能交通安全提供了新的科学研究,并提供了舒适和…

[java] 集合-Collection、ArrayList、LinkedList源码篇

目录 Collection集合 集合类体系结构 常用方法 遍历方式 迭代器遍历 增强for lambda表达式 List集合 特有方法 五种遍历方式 细节点注意 List集合的实现类 List集合子类的特点 LinkedList集合的特有功能 源码分析 ArrayList源码分析 LinkedList源码分析 迭代…

DeepSeek自动化写作软件

DeepSeek写作软件的三大核心功能 对于内容创作者来说,写作不仅是表达思想的过程,更是一项需要投入大量时间和精力的任务。面对日益增长的内容需求,写作效率低下、内容质量不高等问题,常常让创作者感到焦虑。而 DeepSeek 写作软件…

前端里的this指向问题

目录 1.代码输出结果 2.代码输出结果 3.代码输出结果 4.代码输出结果 5.代码输出结果 6.代码输出结果 7.代码输出结果 8.代码输出结果 9.代码输出结果 10.代码输出结果 11.代码输出结果 12.代码输出结果 13.代码输出结果 14.代码输出结果 总结 1.代码输出结果 f…

苹果CMS新版站群管理更新_新增批量生成插件优势何在

引言 随着互联网的发展,站群管理成为了网站运营者提升流量和SEO效果的重要策略。苹果CMS新版站群管理系统通过引入批量生成插件,为用户提供了更高效、更智能的解决方案。本文将详细介绍这一更新的功能特点及其优势。 站群管理功能特点 多域名独立配置…

时序约束进阶八:时钟抖动Jitter与不确定性Uncertainty

目录 一、前言 二、时钟抖动 2.1 时钟抖动类型 2.2 set_input_jitter 2.3 set_system_jitter 2.4 set_clock_uncertainty 2.5 设计代码 2.6 约束解析 2.7 Input_jitter报告 2.8 System Jitter报告 2.9 Clock Uncertainty报告 2.9.1 Uncertainty的计算 2.9.2 Uncer…

小米 R3G 路由器(Pandavan)实现网络打印机功能

小米 R3G 路由器(Pandavan)实现网络打印机功能 一、前言 家中有多台 PC 设备需要打印服务,但苦于家中的 Epson L380 打印机没有网络打印功能,并且配置 Windows 共享打印机实在是过于繁琐且需要共享机保持唤醒状态过于费电。想到…

Leetcode Hot100 第30题 416.分割等和子集

class Solution { public:bool canPartition(vector<int>& nums) {int sum0;for(int num:nums){sumnum;}if(sum%21) return false;int bag_size sum/2;// return dfs(nums,nums.size()-1,bag_size);//递归做法vector<vector<bool>> dp(nums.size()1,vec…

技术晋升读书笔记—阿里管理三板斧(二)

一、引子 美团王兴问马云&#xff1a;“你最强的地方是什么&#xff1f;” 马云反问王兴&#xff1a;“你觉得呢&#xff1f;” 王兴回答&#xff1a;“战略和忽悠。” 马云哈哈大笑&#xff0c;笑完&#xff0c;他一本正经地说&#xff1a;“我最强的地方是管理。” &quo…

引入了 Disruptor 后,系统性能大幅提升!

Disruptor 是一个很受欢迎的内存消息队列&#xff0c;它源于 LMAX 对并发、性能和非阻塞算法的研究。今天一起来学习一下这个消息队列。 简介 对于主流的分布式消息队列来说&#xff0c;一般会包含 Producer、Broker、Consumer、注册中心等模块。比如 RocketMQ 架构如下&…

【WPSOffice】汇总

写在前面 PPT篇 幻灯片母版 通过母版功能统一幻灯片的样式、字体、颜色等&#xff0c;提高整体一致性。 统一设置模板样式 字体安装 查找到字体并安装。 在WPS PPT&#xff08;WPS演示&#xff09;中&#xff0c;以下是最常用的十个功能&#xff0c;能够帮助用户高效制作…

鸿蒙开发:熟知@BuilderParam装饰器

前言 本文代码案例基于Api13。 在实际的开发中&#xff0c;我们经常会遇到自定义组件的情况&#xff0c;比如通用的列表组件&#xff0c;选项卡组件等等&#xff0c;由于使用方的样式不一&#xff0c;子组件是动态变化的&#xff0c;针对这一情况&#xff0c;就不得不让使用方把…

在Nodejs中使用kafka(一)安装使用

安装 方法一、使用docker-compose安装 1、创建docker-compose.yml文件。 services:zookeeper:image: docker.io/bitnami/zookeeper:3.9ports:- "2181:2181"volumes:- "./data/zookeeper:/bitnami"environment:- ALLOW_ANONYMOUS_LOGINyeskafka:image: …

CRISPR spacers数据库;CRT和PILER-CR用于MAGs的spacers搜索

iPHoP&#xff1a;病毒宿主预测-CSDN博客 之前介绍了这个方法来预测病毒宿主&#xff0c;今天来介绍另一种比较用的多的方法CRISPR比对 CRISPR spacers数据库 Dash 在这可以下载作者搜集的spacers用于后期比对 CRT和PILER-CR 使用 CRT 和 PILERCR 识别 CRISPR 间隔区&#x…

深入理解Java的 JIT(即时编译器)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

LabVIEW开发CANopen紧急对象读取

本示例展示了如何通过CANopen协议读取设备的紧急对象&#xff08;Emergency object&#xff09;。紧急对象用于报告设备发生故障或异常情况时的紧急信息。通过该示例&#xff0c;用户可以配置并读取设备发送的紧急消息&#xff0c;确保在设备发生紧急状况时能够及时响应。 主要…

DeepSeek官方推荐的AI集成系统

DeepSeek模型虽然强大先进&#xff0c;但是模型相当于大脑&#xff0c;再聪明的大脑如果没有输入输出以及执行工具也白搭&#xff0c;所以需要有配套工具才能让模型发挥最大的作用。下面是一个典型AI Agent架构图&#xff0c;包含核心组件与数据流转关系&#xff1a; #mermaid-…