【JavaSE篇】——抽象类和接口

news2024/10/6 6:01:29

目录

🎓抽象类

🎈抽象类语法

🎈抽象类特性

🎈抽象类的作用

🎓接口

🎈语法规则

🎈接口特性

🎈接口使用(实现USB接口)

🎈实现多个接口

🎈接口间的继承

🎈接口使用实例 (给对象数组排序)

🌈Comparable接口<比较>

🌈Comparator接口<比较器>

🚩抽象类和接口的区别

🎓抽象类

抽象类自己本身是不具有什么特性的,就比如Shape类中我们有draw方法,但是Shape并没有什么具体的形状,而继承的子类比如三角形类,矩形类,圆形类等都是在有具体图形,我们称Shape类是抽象类。

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

 


在打印图形例子中 , 我们发现 , 父类 Shape 中的 draw 方法好像并没有什么实际工作 , 主要的绘制图形都是由 Shape的各种子类的 draw 方法来完成的 . 像这种没有实际工作的方法 , 我们可以把它设计成一个 抽象方法 (abstract method) , 包含抽象方法的类我们称为 抽象类 (abstract class)

🎈抽象类语法

Java 中,一个类如果被 abstract 修饰 称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法, 抽象方法不用给出具体的实现体
// 抽象类:被abstract修饰的类
abstract class Shape1{
    // 抽象方法:被abstract修饰的方法,没有方法体
    abstract public void draw();
    abstract void calcArea();
    // 抽象类也是类,也可以增加普通方法和属性
    public int age;
    public void func(){};
}
注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法

🎈抽象类特性

1. 抽象类不能直接实例化对象 new   

肯定很多人疑问,抽象类不能实例化对象,那么存在意义在哪?—抽象类存在的意义是为了被继承

public class Test {
    Shape1 shape1=new Shape1();
}
//Shape1是抽象类,不能实例化

2.抽象类和普通类不一样的是抽象类可以包含抽象方法,可以包含普通类所包含的成员(上述语法已讲述)

3.抽象类和抽象方法都是由abstract修饰的,方法中没有具体的实现体(上述语法)
 4.抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰(被abstract修饰就不用重写方法,应用于有些类不需要这个方法)
abstract class Shape1{
    // 抽象方法:被abstract修饰的方法,没有方法体
    abstract public void draw();
}
class Cycle1 extends Shape1{
    @Override
    public void draw() {
        System.out.println("画⚪");
    }
}

5.如果一个抽象类B继承了一个抽象类A,此时B当中不需要重写A的重写方法,但如果B再被

普通类继承,就需要重写。


6.抽象方法不能被private,final和static修饰,因为抽象方法要被子类重写
我们可以这样想,方法就是为了重写设置成私有的,怎么能被重写?
并且我们在 重写的时候说到 (java子类方法权限要等于大于父类的访问权限?)
7. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
8. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
❗A类
abstract class A{
    public int age;
    public String name;
    public A(int age,String name){
        this.age=age;
        this.name=name;
    }
    abstract public void func();

❗B类

class B extends A{
    public B(){
        super(8,"chenle");
    }
    public void func(){
        System.out.println("sadasd");
    }
}

❗运行区


🎈抽象类的作用

抽象类本身不能被实例化 , 要想使用 , 只能创建该抽象类的子类 . 然后让子类重写抽象类中的抽象方法 .
有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法
呢
确实如此 . 但是使用抽象类相当于多了一重编译器的校验 .
使用抽象类的场景就如上面的代码 , 实际工作不应该由父类完成, 而应由子类完成 . 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的 . 但是父类是抽象类就会在实例化的时候提示错误 , 让我们尽早发现问题/。
很多语法存在的意义都是为了 " 预防出错 ", 例如我们曾经用过的 final 也是类似 . 创建的变量用户不去修改 , 不就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候 , 让编译器及时提醒我们 .
充分利用编译器的校验 , 在实际开发中是非常有意义的 .

🎓接口

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

🎈语法规则

接口的定义格式与定义类的格式基本相同,将 class关键字换成 interface 关键字 ,就定义了一个接口。
public interface 接口名称{
// 抽象方法
public abstract void method1(); // public abstract 是固定搭配,可以不写
public void method2();
abstract void method3();
void method4();
// 注意:在接口中上述写法都是抽象方法,跟推荐方式4,代码更简洁
}
提示:
1. 创建接口时, 接口的命名一般以大写字母 I 开头.
2. 接口的命名一般使用 "形容词" 词性的单词.
3. 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性

🎈接口特性

1.使用interface来修饰接口

2.接口当中的成员方法,不能有具体的实现  [默认是public]

所以子类的重写方法不能默认不写,子类的重写方法是default,而子类的访问权限要大于父类的访问权限,所以我们必须在子类中的重写方法前写上public

  • 抽象方法:默认是public abstract方法
  • JDK1.8开始 ,允许有可以实现的方法,但是这个方法只能由default修饰
  • 可以实现一个静态方法
interface Ishape{
    public abstract void draw();//抽象方法
    void draw();//这是最好的表达抽象方法方式

     default public  void draw1(){
        System.out.println("默认方法");
    }

    public static void draw2(){
        System.out.println("静态方法");
    }
}

3.成员变量默认是public static final 修饰的(是不能修改的)

   成员方法 默认是public abstract 修饰(其他修饰符都是错的)

 public static final int age=10;//public static final
    void draw3();//public abstract

4.接口不能被实例化(抽象类也不能实例化)因为接口中的方式默认为抽象方法

5.类和接口之间采用implements来实现多个接口

一旦类实现接口之后,就必须重写这个接口里面的抽象方法。接口里的普通成员方法可以重写也可以不重写。

interface Itest{
    void draw3();//public abstract
    default public  void draw1(){
        System.out.println("默认方法");
    }
    public static void draw2(){
        System.out.println("静态方法");
    }
}
class Cycle implements Itest{
    @Override
    public void draw3() {
        System.out.println("必须重写");
    }

    @Override
    public void draw1() {
        System.out.println("可以重写也可以不重写");
    }
}

6.将接口想象成特殊的类,我们可以当作参数,接口不能实例化,但是可以new普通的类。

interface Ishape{
    void draw();
}
class Cycle implements IShape{
    @Override
    public void draw() {
        System.out.println("画⚪");
    }
}
class Rect implements IShape{

    @Override
    public void draw() {
        System.out.println("画矩形");
    }
}

class Flowers implements IShape{

    @Override
    public void draw() {
        System.out.println("画❀");
    }
}
public class Test3 {
    public static void Map(IShape iShape){
        iShape.draw();
    }
    public static void main(String[] args) {
        Cycle cycle=new Cycle();
        Map(cycle);
        Map(new Flowers());
        Map(new Rect());
    }

相当于 Ishape ishape=new Cycle();

            ishape.draw();实现创建对象,进行对接口的调用。

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

一个接口就是一个java文件

 

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

9.如果不想实现接口的方法,那么就将这个类定义成抽象类,但是如果这个类被其他类继承,那么必须重写。(这个和抽象类类似)

 


🎈接口使用(实现USB接口)

接口不能直接使用,必须要有一个 " 实现类 " " 实现 " 该接口,实现接口中的所有抽象方法。
public class 类名称 implements 接口名称{
// ...
}
注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系
请实现笔记本电脑使用 USB 鼠标、 USB 键盘的例子
1. USB 接口:包含打开设备、关闭设备功能
2. 笔记本类:包含开机功能、关机功能、使用 USB 设备功能
3. 鼠标类:实现 USB 接口,并具备点击功能
4. 键盘类:实现 USB 接口,并具备输入功能
package Interfaces;

//USB接口
interface Iusb{
    void openDevice();
    void closeDevice();
}
//鼠标类
class Mouse implements Iusb{

    @Override
    public void openDevice() {
        System.out.println("打开鼠标");
    }

    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("点击鼠标");
    }
}

// 键盘类,实现USB接口
class KeyBoard implements Iusb {
    @Override
    public void openDevice() {
        System.out.println("打开键盘");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭键盘");
    }
    public void inPut(){
        System.out.println("键盘输入");
    }
}

// 笔记本类:使用USB设备
class Computer {
    public void powerOn() {
        System.out.println("打开笔记本电脑");
    }

    public void powerOff() {
        System.out.println("关闭笔记本电脑");
    }
    public static void useDevice(Iusb iusb){
        iusb.openDevice();
        if(iusb instanceof Mouse){
            Mouse mouse=(Mouse) iusb;
            mouse.click();
        }else if(iusb instanceof KeyBoard){
            KeyBoard keyBoard=(KeyBoard) iusb;
            keyBoard.inPut();
        }
        iusb.closeDevice();
    }

}
public class Test4 {

    public static void main(String[] args) {
        Computer computer = new Computer();
        //打开设备
        computer.powerOn();
        //使用鼠标设备
        computer.useDevice(new Mouse());
        //使用键盘设备
        computer.useDevice(new KeyBoard());
        //关闭设备
        computer.powerOff();
    }
}


🎈实现多个接口

Java 中,类和类之间是单继承的,一个类只能有一个父类,即 Java 中不支持多继承 ,但是 一个类可以实现多个接 。【单继承多接口】下面通过类来表示一组动物 .

一个类可以实现多个接口。使用implements用逗号隔开。【可以解决多继承的问题】


我们可以定义一个动物类,然后狗类继承了动物类,我们实现多个接口,有些动物是又会飞又会跑,又会游泳的。

interface Running{
    void run();
}
interface Flying{
    void fly();
}
interface Swimming{
    void swim();
}

我们实现多个接口,而不是实现多个类,因为java中只能继承一个类,而不能继承多个类,但是一个类可以实现多个接口。我们不需要创建一个swim类,fiy类,run类,然后里面有自己的swim,fly,run的成员方法,然后狗类一个一个继承,因为java中不能多继承,所以代码的重复,而实现多个接口正是可以解决java中的多继承问题,让一个狗类同时implement多个接口,然后重写方法,即可完成了一个类继承多个接口的方法。

❗各接口

interface Running{
    void run();
}
interface Flying{
    void fly();
}
interface Swimming{
    void swim();
}

❗Animal类和各种子类

class Animal{
    int age;
    String name;
    Animal(int age,String name){
        this.age=age;
        this.name=name;
    }
    void eat(){
        System.out.println("正在吃饭");
    }
}

class Dog extends Animal implements Running,Swimming{

    public Dog(int age, String name) {
        super(age, name);
    }
    @Override
    public void run() {
        System.out.println(name+"正在跑");
    }

    @Override
    public void swim() {
        System.out.println(name+"正在游泳");
    }
    public void eat(){
        System.out.println(name+"吃狗粮");
    }

}
class Bird extends Animal implements Flying{
    public Bird(int age, String name) {
        super(age, name);
    }

    @Override
    public void fly() {
        System.out.println(name+"正在飞");
    }

    public void eat(){
        System.out.println(name+"吃鸟粮");
    }
}
class Duck extends Animal implements Flying,Swimming,Running{

    public Duck(int age, String name) {
        super(age, name);
    }

    public void run() {
        System.out.println(name+"正在跑");
    }

    @Override
    public void swim() {
        System.out.println(name+"正在游泳");
    }

    public void fly() {
        System.out.println(name+"正在跑");
    }
    public void eat(){
        System.out.println(name+"吃鸭粮");
    }
}

测试方法

public class Test6 {
    public static void walk(Running running){
        running.run();
    }
    public static void func(Animal animal){
        animal.eat();
    }
    public static void main(String[] args) {
        walk(new Dog(13,"chq"));
        walk(new Duck(12,"chhh"));
    }
}

🎈接口间的继承

Java 中,类和类之间是单继承的,一个类可以实现多个接口, 接口与接口之间可以多继承 。即:用接口可以达到多继承的目的。
接口可以继承一个接口 , 达到复用的效果 . 使用 extends 关键字 .

就是说我们D1类是一个既能完成A1的行为,也能完成B1的行为,还能完成C1接口行为,然后我们接口C1继承了A1和B1的接口,其实C1继承A1和B1的行为,就相当于如果类实施了C1,那么这三个A1,B1,C1都是行动的。

接口间的继承相当于把多个接口合并在一起.

🎈接口使用实例 (给对象数组排序)

❗Animal类

class Student{
    public int age;
    public String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

❗运行 

这段代码是错误的,我们不管是按照什么来排序的,不管是年龄还是姓名都是错误的,我们可以来分析一下这段错误。

仔细思考 , 不难发现 , 和普通的整数不一样 , 两个整数是可以直接比较的 , 大小关系明确 . 而两个学生对象的大小关系怎么确定? 需要我们额外指定 .

🌈Comparable接口<比较>

让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法


✅按照年龄来比较(Comparable 接口, 并实现其中的 compareTo 方法)

class Student implements Comparable<Student>{
    public int age;
    public String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        if(this.age>o.age){
            return 1;
        }else if(this.age<o.age){
            return -1;
        }else{
            return 0;
        }
    }
}

当Student类实施了Comparable接口并且实现了compareTo方法,我们就可以根据年龄来进行比较。



我们可以看到底层,底层代码的比较是调用compareTo方法比较

 public static void main(String[] args) {
        Student student1=new Student(18,"chenle");
        Student student2=new Student(13,"zhang");
       if(student1.compareTo(student2)>0){
           System.out.println("student1>student2");
       }else {
           System.out.println("student2>student1");
       }
    }


🌈Comparator接口<比较器>

✅按照姓名来比较(实现Comparator接口,并实现compare方法)

我们是不能更改age的比较方法,那样势必回影响后面的运行,如果代码已经运行了一个月了,如果更改会影响很多。

所以我们需要利用 另外一个接口Comparator<T>以及接口里的compare方法

Comparator<T>接口中有很多方法,我们只需要compare抽象方法即可。



❗AgeCompare 

class AgeCompare implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}

❗运行 

 public static void main(String[] args) {
        Student[] students=new Student[3];
        students[0]=new Student(18,"chenle");
        students[1]=new Student(13,"zhang");
        students[2]=new Student(9,"hao");
        AgeCompare ageCompare=new AgeCompare();
        Arrays.sort(students,ageCompare);
        System.out.println(Arrays.toString(students));
    }



❗NameCompare 

因为比较字符串的底层是利用Comparable接口中的compareTo方法

class NameCompare implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}

❗运行 

 public static void main(String[] args) {
        Student[] students=new Student[3];
        students[0]=new Student(18,"chenle");
        students[1]=new Student(13,"zhang");
        students[2]=new Student(9,"hao");
        NameCompare nameCompare=new NameCompare();
        Arrays.sort(students,nameCompare);
        System.out.println(Arrays.toString(students));
    }



我个人更推荐第二种,我们自己单独设置个类,然后我们直接利用比较器比较,如果比较整型直接return俩者相减即可,如果比较字符串,我们需要利用到compareTo方法进行比较。


🚩抽象类和接口的区别

核心区别 : 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用 ( 不必重写 ), 接口中不能包含普通方法,只能是抽象方法 , 子类必须重写所有的抽象方法。
如之前写的 Animal 例子 . 此处的 Animal 中包含一个 name 这样的属性 , 这个属性在任何子类中都是存在的 . 因此此处的 Animal 只能作为一个抽象类 , 而不应该成为一个接口
再次提醒 :
抽象类存在的意义是为了让编译器更好的校验 , Animal 这样的类我们并不会直接使用 , 而是使用它的子类 .万一不小心创建了 Animal 的实例 , 编译器会及时提醒我们


祝你逃出苦难向春山。

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

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

相关文章

深度学习系列57: 清华大模型MiniCPM上手

MiniCPM 是面壁智能与清华大学自然语言处理实验室共同开源的系列端侧大模型&#xff0c;主体语言模型 MiniCPM-2B 仅有 24亿&#xff08;2.4B&#xff09;的非词嵌入参数量 1. 上手对比测试 mps比cpu大概快了9倍左右。 也可以在modelspore上测试&#xff1a;

【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题

目录 1、题目介绍 2、解题思路 2.1、暴力破解法 2.2、经典Next Greater Number问题解法 1、题目介绍 原题链接&#xff1a;496. 下一个更大元素 I - 力扣&#xff08;LeetCode&#xff09; 示例1&#xff1a; 输入&#xff1a;nums1 [4,1,2], nums2 [1,3,4,2].输出&…

AMH面板如何安装与公网远程访问本地面板界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

html2Canvas截取百度地图问题整理及解决方案

目录 一、截图地图打点出不来二、截图报错Uncaught (in promise)html2Canvas属性大全 一、截图地图打点出不来 1.开启foreignObjectRendering 原因是地图打点中含有svg var canvas await html2canvas(obj, {useCORS: true, foreignObjectRendering: true})2.页面图片转base6…

Multi ElasticSearch Head插件基本操作

Multi ElasticSearch Head插件安装好之后我们可以进行一些基本的操作。 1、复合查询 因为ES提供了一些Restful风格的接口&#xff0c;可以让任何语言去调用&#xff0c;因此我们可以将之前的请求地址粘贴到Multi ElasticSearch Head插件里面&#xff0c;选择GET请求方式&#x…

WordPress主题YIA如何将首页的置顶小工具改为站长推荐小工具?

YIA主题有“置顶推荐”小工具&#xff0c;首页文章列表页有置顶功能&#xff0c;可在YIA主题设置 >> 列表 >> 首页-最新发布 >> 显示置顶文章中开启或关闭。如果将“置顶推荐”小工具添加到“首页顶栏”&#xff0c;同时也开启首页最新发布的“显示置顶文章”…

Java使用规范

1.关键字 定义&#xff1a;被Java语言赋予了特殊含义&#xff0c;用做专门用途的字符串(单词) 特点&#xff1a;关键字中的所有字母都是小写 2.保留字 java保留字&#xff1a;现有Java版本尚未使用&#xff0c;但以后的版本可能会作为关键字使用。命名标识符时要避免使用这些…

C# wpf 字体图标预览,html字符与unicode转换

在进行wpf 开发工作过程中遇到字体图标无法预览的问题&#xff0c;特此记录。 1、把需要预览的字体文件上传到网站上进行转换 Create Your Own font-face Kits Font Squirrel2、下载文件后进行解压。 3、找到 Glyph Chart 查看字体html字符编码4、在wpf中直接使用即可 <…

C#,河豚算法(Blowfish Algorithm)的加密、解密源代码

Bruce Schneier 1 河豚算法&#xff08;Blowfish Algorithm&#xff09; 河豚算法&#xff08;Blowfish Algorithm&#xff09;是1993年11月由Bruce Schneier设计的一个完全开源的算法。 Blowfish算法是一个分组长度为64位、密钥长度可变的对称分组密码算法。 Blowfish算法具…

Redis 持久化对性能有何影响?

Redis 持久化对性能的影响 Redis 是一个高性能的内存数据存储系统&#xff0c;通常被用于缓存、消息队列和数据存储等方面。由于 Redis 是基于内存的&#xff0c;因此它的读写速度非常快&#xff0c;可以满足高并发、低延迟的应用需求。但是&#xff0c;当 Redis 需要持久化数…

Git的一些基本操作

初始git 我们给出下面的一个场景&#xff0c;在大学里&#xff0c;一些老师在我们做完实验之后喜欢让我们交实验报告&#xff0c;假设我们有一个比较追求完美的老师和一个勤奋的学生&#xff0c;这个学生叫做小帅&#xff0c;那天小帅桑勤奋的完成实验报告&#xff0c;在第二天…

L1-016 查验身份证-java

输入样例1&#xff1a; 4 320124198808240056 12010X198901011234 110108196711301866 37070419881216001X输出样例1&#xff1a; 12010X198901011234 110108196711301866 37070419881216001X输入样例2&#xff1a; 2 320124198808240056 110108196711301862输出样例2&#…

银行数据仓库体系实践(18)--数据应用之信用风险建模

信用风险 银行的经营风险的机构&#xff0c;那在第15节也提到了巴塞尔新资本协议对于银行风险的计量和监管要求&#xff0c;其中信用风险是银行经营的主要风险之一&#xff0c;它的管理好坏直接影响到银行的经营利润和稳定经营。信用风险是指交易对手未能履行约定契约中的义务而…

【AIGC核心技术剖析】DreamCraft3D一种层次化的3D内容生成方法

DreamCraft3D是一种用于生成高保真、连贯3D对象的层次化3D内容生成方法。它利用2D参考图像引导几何塑造和纹理增强阶段&#xff0c;通过视角相关扩散模型执行得分蒸馏采样&#xff0c;解决了现有方法中存在的一致性问题。使用Bootstrapped Score Distillation来提高纹理&#x…

Backtrader 文档学习- Observers

Backtrader 文档学习- Observers 1.概述 在backtrader中运行的策略主要处理数据源和指标。 数据源被加载到Cerebro实例中&#xff0c;并最终成为策略的一部分&#xff08;解析和提供实例的属性&#xff09;&#xff0c;而指标则由策略本身声明和管理。 到目前为止&#xff0c…

python文字识别

Tesseract 文字识别是ORC的一部分内容&#xff0c;ORC的意思是光学字符识别&#xff0c;通俗讲就是文字识别。Tesseract是一个用于文字识别的工具。 Tesseract的安装及配置 https://digi.bib.uni-mannheim.de/tesseract/ 在上述链接下载自己需要的版本。下载后安装&#xff…

chisel之scala 语法

Chisel新手教程之Scala语言&#xff08;1&#xff09; Value & variable Value是immutable的&#xff0c;当它被分配一个数据后&#xff0c;无法进行重新分配。用 val 表示。 Variable是mutable的&#xff0c;可以重复赋值。用 var 表示。示例如下&#xff1a; val a …

视觉SLAM十四讲学习笔记(一)初识SLAM

目录 前言 一、传感器 1 传感器分类 2 相机 二、经典视觉 SLAM 框架 1 视觉里程计 2 后端优化 3 回环检测 4 建图 5 SLAM系统 三、SLAM 问题的数学表述 四、Ubuntu20.04配置SLAM十四讲 前言 SLAM: Simultaneous Localization and Mapping 同时定位与地图构建&#…

R语言阈值效应函数cut.tab2.0版发布(支持线性回归、逻辑回归、cox回归,自定义拐点)

阈值效应和饱和效应是剂量-反应关系中常见的两种现象。阈值效应是指当某种物质的剂量达到一定高度时&#xff0c;才会对生物体产生影响&#xff0c;而低于这个剂量则不会产生影响。饱和效应是指当某种物质的剂量达到一定高度后&#xff0c;其影响不再随剂量的增加而增加&#x…

2024-2-4-复习作业

源代码&#xff1a; #include <stdio.h> #include <stdlib.h> typedef int datatype; typedef struct Node {datatype data;struct Node *next;struct Node *prev; }*DoubleLinkList;DoubleLinkList create() {DoubleLinkList s(DoubleLinkList)malloc(sizeof(st…