抽象类与接口(3)(接口部分)

 ❤️❤️前言~🥳🎉🎉🎉 

hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥💥,如果发现这篇文章有问题的话,欢迎各位评论留言指正,大家一起加油!一起chin up!👍👍 

💥个人主页:E绵绵的博客
💥 所属专栏:JAVASE题目练习  JAVASE知识点专栏  c语言知识点专栏   c语言题目练习
 

 这篇文章就是关于抽象类与接口的最后一篇了,我们接下来将会给大家主要介绍接口的实例使用,这部分也是最难的,还请各位认真观看,不要错过每一处细节。💕💕 

接口使用实例  

给对象数组排序

首先在了解它之前我们一些接口以及其他知识点。

comparable  

 ❤️❤️观察其内部结构我们可以知道在Comparable后面还有个<T>,在语法上这是泛型,之后会讲,这并不影响我们现在的思路,这个<T>中的T你写student类,后面的compareTo方法中的第一个参数就是student类,如上图。

对于comparable接口中只有一个compareTo方法,所以我们使用该接口时只需要重写该compareTo方法就行。

比较大小时可以用comparable该接口。

关于其comprable使用如下:

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

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

   @Override
    public int compareTo(Student o) {
        //System.out.println("===fdsfsafdsafdsafdsafdsafdsafsafdsafa");
        return this.age - o.age;
    }

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


    public static void bubbleSort(Comparable[] comparables) {

        for (int i = 0; i < comparables.length-1; i++) {
            for (int j = 0; j < comparables.length-1-i; j++) {

                if(comparables[j].compareTo(comparables[j+1]) > 0) {
                    Comparable tmp = comparables[j];
                    comparables[j] = comparables[j+1];
                    comparables[j+1] = tmp;
                }
            }
        }
    }

    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan",10);
        students[1] = new Student("lisi",4);
        students[2] = new Student("abc",5);
        System.out.println("排序前: "+Arrays.toString(students));

        bubbleSort(students);

        System.out.println("排序后: "+Arrays.toString(students));
    }

所以就通过该代码去使用comparable接口中的compareTo方法,这个代码你们自己仔细看一下应该就能看懂了,不细讲,讲个大概就行了。

tostring重写 

在上文代码中出现了一个问题,就是当Arrays.toString内部为类数组时如students时,为什么要将toString重写,(注意这里的toString重写不是将Arrays的toString重写,是将内部的object中的tostring重写)原因如下:

请看下面的图片:

分析上述图得知,当其内部为像students时的类数组时,不重写则会打印出地址

我们的目的是打印出其每个类的每个数据,所以要将toString重写,如下

所以就达成了目的,将数组的每个类的每个数据都打印出来了

🎯🎯 所以一般来说我们目前遇到的需要toString重写的就两种情况。

           1.Arrays.toString(存储类的数组)打印出该数组的每个类的每个数据

            2.println(类),打印出该类的各个数据

comparator 

❤️❤️该接口有许多方法,但必须重写的只有一个,就是下图中的compare方法需要重写。

以下是使用方式

class Student  {
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }}
class AgeComparator implements Comparator<Student> {

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

class NameComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {

        //String  自己重写的 compareTo 方法
        return o1.name.compareTo(o2.name);
    }
}
public class Test {

    public static void main(String[] args) {
        { Student student1 = new Student("zhangsan", 10);
            Student student2 = new Student("lisi", 4);
            Test test = new Test();
            test.a(student1,student2);
        }
    }
        public void a(Student student1,Student student2)
    {

        AgeComparator ageComparator = new AgeComparator();
        System.out.println(ageComparator.compare(student1, student2));


        NameComparator nameComparator = new NameComparator();
        System.out.println(nameComparator.compare(student1, student2));
        }
}

该接口中的compare方法也是用来进行比较的。

在该代码中我们还出现了compareTo,不过这里出现的跟我们往常见到的不一样。接下来将介绍一下。

 String类中的compareTo 

 ❤️❤️现在我们虽然还没深入了解String,但是呢还是懂一点的,我们观察下String类的内部。

可以发现它实施了comparable接口,则它一定重写了compareTo方法。

在这了解了内部之后我们只需要知道其string.compareTo的作用为

compareTo方法的实现会按照Unicode值的比较。它会逐个比较两个字符串对应位置上的字符的Unicode值,直到找到不同的字符或者其中一个字符串结束为止。找到不同的字符,会根据它们unicode值确定大小关系。

如果最终一直相等,则返回0,如果调用该方法的字符串小于参数里的字符串,则返回负数  ;反之为正数。

下面是一个例子

​
String str1 = "abc";
String str2 = "def";
int result = str1.compareTo(str2);
System.out.println(result); 
 // 输出负数,表示str1在unicode值上小于str2(也可以认为字典顺序上小于)

​

 正文(给对象数组排序)

class Student  {
    private String name;
    private int score;

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

    }

    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}
public class Main{
    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("张三", 95),
                new Student("李四", 96),
                new Student("王五", 97),
                new Student("赵六", 92),
        };

        Arrays.sort(students);

        System.out.println(Arrays.toString(students));
    }}

报错了这是为什么呢,我们来看下内部结构吧。

所以如果sort()内部参数为类(引用类型)数组,则其对应的代码如上,这里的a是object类,但其实指向的是创建的student类数组,发生了向上转型。下方还出现了comparable强制类型转换,但因为在上文中comparable和student没有任何关系,所以在这会报错,这也是为什么原文代码没有发生编译错误,但运行却报错了,所以我们必须得让comparable和student产生关系,这样代码才能成功。正确代码如下:

class Student implements Comparable<Student> {
    private String name;
    private int score;

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

    }

    @Override
    public int compareTo(Student  this,Student O) {
        return  O.name .compareTo( this.name) ;//逆序,compareTo比较大小


    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}
public class Main{
    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("张三", 95),
                new Student("李四", 96),
                new Student("王五", 97),
                new Student("赵六", 92),
        };

        Arrays.sort(students);

        System.out.println(Arrays.toString(students));
    }}

结果如上,这是对类中的name进行排序,当然我们可以通过改变compareTo中的代码去来改变要排序的成员。

所以当sort参数为类(引用类型)数组时,我们就必须让该类实施comparable接口,并且重写comparable中的compareTo方法使其对类中的某个成员进行排序。(注意其compare to返回值为整形,分为大于0,小于0,0三种)

拷贝

之前就略微讲过拷贝,只不过之前只涉及了浅拷贝,讲的很少,这次我们认真讲下拷贝,它不仅涉及浅拷贝还有深拷贝。 

clone 

❤️❤️object类中存在一个方法为clone,我们可以通过调用该方法来复制该类的对象从而去创建该类的对象的副本。

我们先来看下代码:

class Person implements Cloneable {
    private String name;
    private int age;

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

    // 重写clone()方法
    @Override
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();

    }

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

public class Date{
    public static void main(String[] args)throws  CloneNotSupportedException  {
          Person person=new Person("小美",5);
              Person  person1=person.clone();
        System.out.println(person1);
        }

}

从这代码我们可以注意到一些事项 :

🎯​​​​​​​🎯 1.实现Cloneable接口:要使用clone()方法,需要确保被复制的类实现了Cloneable接口。否则,在调用clone()方法时会抛出CloneNotSupportedException异常。

而被复制的类的对象实则是引用clone方法的类对象。如上文中的peson。

 🎯​​​​​​​🎯2重写clone()方法:被复制的类需要重写clone()方法,并将其访问修饰符设置为public。在重写的clone()方法中,我们通过调用父类的clone()方法来实现对象的浅拷贝。

如下:

   public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

之所以要重写clone,是因为clone是被protected修饰,只能在object的同一个包中或不同包的子类中出现。这时如果不重写clone,直接在Date类里引用person.clone,那么就会因为这是person里的clone,而clone在不同包中的非子类Date中出现,所以受访问权限不能访问。因此需要在person类里重写clone方法。(一般重写为如上代码格式)

🎯​​​​​​​🎯 3.异常处理:在调用clone()方法时,可能会抛出CloneNotSupportedException异常。因此,在使用clone()方法时,需要在使用clone()方法中的成员方法上声明抛出该异常,否则会报错。  

throws  CloneNotSupportedException就是该异常声明

​​

🎯​​​​​​​🎯4.注意clone返回的是object类型,所以在接收时我们还需要强制类型转换才能成功。

🎯​​​​​​​🎯5. 

先看代码

​
​
class Money implements Cloneable{
    public double m = 19.9;
}
class Person implements Cloneable{
    public String name;
    public int age;

    public Money money = new Money();

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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", money=" + money.m +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {


        Person tmp = (Person)super.clone();
        return super.clone();
    }}
public class Date {
    public static void main(String[] args) throws  CloneNotSupportedException{
        Person person=new Person("0",99);

        Person person1= (Person) person.clone();
        person.money.m=99.9;
        System.out.println(person);
        System.out.println(person1);

    }
}

​

​

之所以会出现两个99.9,是因为默认情况下,clone()方法执行的是浅拷贝,即复制对象的引用,不会将引用所指向的对象一并复制,所以person1中的money指向的依然是同一个对象,依然是99.9.那如果需要实现深拷贝,即复制对象的内容而不是引用,需要在clone()方法中手动处理对象内部的引用。

如下才是深拷贝真正代码:

class Money implements Cloneable{
    public double m = 19.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public String name;
    public int age;

    public Money money = new Money();

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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", money=" + money.m +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {


        Person tmp = (Person)super.clone();
        tmp.money = (Money) this.money.clone();
        return tmp;

    }}
public class Date {
    public static void main(String[] args) throws  CloneNotSupportedException{
        Person person=new Person("0",99);

        Person person1= (Person) person.clone();
        person.money.m=99.9;
        System.out.println(person);
        System.out.println(person1);

    }
}

我们手动处理了对象内部的引用,所以money类的对象也被复制了,两个money引用所指向的对象不同,导致如上结果不同。

深拷贝和浅拷贝

❤️❤️深拷贝和浅拷贝是在Java中用于复制对象的两种不同方式。由上文可知,我们可以知道深拷贝和浅拷贝的区别:

浅拷贝是指创建一个新对象,然后将原始对象的成员变量的值复制到新对象中。如果成员变量是基本类型,则复制其值;如果成员变量是引用类型,则复制引用而不是其指向的实际对象。因此,始对象和新对象将共享相同的引用对象。这意味着,如果修改其中一个对象的引用对象,另一个对象也会受到影响。

深拷贝是指创建一个新对象,并复制原始对象的所有成员变量及其所有引用变量所指向的对象。这意味着,虽然原始对象和新对象将拥有相同的值(引用变量的值不同,因为指向不同对象),但是它们引用的是不同的对象。因此,修改其中一个对象的引用对象不会影响另一个对象。

对于浅拷贝我们能通过clone()实现。

而深拷贝我们能通过Serializable接口去实现,这个我们之后会学习,现在还没到那个时候。

抽象类和接口的区别 

❤️❤️抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! 常见面试题).

核心区别:

1.抽象类中可以包含方法和成员变量, 这样的方法和成员变量可以被子类直接使用(不必重写)

2.接口中只能有抽象方法,default或static修饰的方法,。子类必须重写所有的抽象方法.

再次提醒: 抽象类存在的意义是为了让编译器更好的校验, 像 Animal 这样的类我们并不会直接使用, 而是使用它的子类. 万一不小心创建了 Animal 的实例, 编译器会及时提醒我们.

Object类 

🎯​​​​​​​🎯Object是Java默认提供的一个类。之前也讲过,Java里面当类没继承关系时,会默认将Object类当作父类,所以所有的类都会继承Object类。它有可能是父类,也有可能是父类的父类等。所以所有类的对象都可以使用Object的引用进行接收。

对于object类,不需要自己主动将其类导入。系统会默认帮你导入这个object类。

 ❤️❤️范例:使用Object接收所有类的对象:

class Person{}
class Student{}
public class Test {
 public static void main(String[] args) {
 function(new Person());
 function(new Student());
 }
 public static void function(Object obj) {
 System.out.println(obj);
 }
}
//执行结果:
Person@1b6d3586
Student@4554617c

所以在开发之中,Object类是参数的最高统一类型,所有类都可以用它接收。并且我们的Object类内部还存在定义好的一些方法。如下:

对于object类的方法,我们目前要了解的有四个,clone(),toString(),equals(),hashcode()。刚才已经讲过了clone(),所以现在讲解一下其他三个。

tostring获取对象信息 

💞 💞对于object里的tostring(),如果参数是基本类型变量,则返回其基本类型变量的值。如果参数是引用类型变量,返回其引用变量的值(地址)。(注意返回值是String类型,所以都要带双引号)

所以如果我们要打印出对象中的内容,用object里的tostring()是没用的,我们需要直接重写Object类中的toString()方法,对于这个重写我们之前已经讲过了,此处不再累赘。这里直接看一个很典型的重写代码:

 public String toString() {
        return "Person{" +
                "age=" + age +
                ", money=" + money.m +
                '}';
    }

 equals方法

❤️❤️在Java中,用==进行比较时:分为两种:

如果==左右两侧是基本类型变量,比较的是变量中值是否相同

如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同

对于我们的equals,它适用于类的对象的比较。以下是其equals内部代码:

// Object类中的equals方法
public boolean equals(Object obj) {
    return (this == obj);   // 使用引用中的地址直接来进行比较
}

通过观察以上代码可知,因为其参数为object,所以适用于类的对象的比较。

而通过对其观察,因为其object的equals方法是直接拿地址进行比较,所以我们要比较对象中内容时,必须重写Object中的equals方法,否则会得到错误结果。

如下:

class Person{
 private String name ; 
 private int age ; 
 public Person(String name, int age) {
 this.age = age ; 
 this.name = name ;
 }
}
public class Test {
 public static void main(String[] args) {
 Person p1 = new Person("gaobo", 20) ; 
 Person p2 = new Person("gaobo", 20) ; 
        int a = 10;
        int b = 10;
        System.out.println(a == b);             // 输出true
 System.out.println(p1 == p2);           // 输出false
        System.out.println(p1.equals(p2));      // 输出false
 }
}

此时无论如何,用equals方法比较两个类对象其结果都是false,所以比较类的对象中内容是否相同的时候,一定要重写equals方法。

对于该重写方法我们可以通过快捷键自动生成equals重写方法:

对于该代码,在正常情况下我们主要考虑最后一段代码

我们观察下objects.equals的内部代码

这里有疑惑的是又出现了equals,如果这里的a和b是普通类的话,那么它们直接比较地址不就返回false,结果不又是一直false的吗,所以我们引出下文:

在String类中,equals跟compareTo一样都被重写了,为上图代码。通过该代码可知,只要两个字符串完全相等,则返回true,否则false。

所以只要是有String类.equals方法,那么就会引用String类中的equals的重写方法,从而判断字符串是否相等。

所以我们现在就很好的分析完这段代码以及其内部代码了,懂得了equals方法的相关知识点。

hashcode方法

对于hashCode()这个方法,它的作用:它能帮我算出对象的具体位置,而这里面涉及数据结构,但是我们还没学数据结构,没法讲述,所以我们只能说它是个内存地址。我们要等到学哈希表才能真正清楚的去讲述清楚它。所以先放一下这个hashcode方法,之后再讲清楚。

 总结 

所以这就是我们的抽象类与接口的最后一章,里面涉及的知识点过多,还请大家认真多看几遍,好好消化。一起加油吧!帮作者点点关注,评评论谢谢家人们了~❤️❤️🥳🎉🎉🎉

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TiDB单机版安装和连接访问

TiDB单机版安装和连接访问 1、下载 $wget http://download.pingcap.org/tidb-latest-linux-amd64.tar.gz 2、解压缩 $tar -zxvf tidb-latest-linux-amd64.tar.gz 3、启动TiDB 启动PD $./bin/pd-server --data-dirpd --log-filepd.log 启动tikv $./bin/tikv-server --pd…

基于深度学习的扑克牌识别软件(网页版+YOLOv8_v7_v6_v5代码+训练数据集)

摘要&#xff1a;本文深入研究了基于YOLOv8/v7/v6/v5的扑克牌识别软件&#xff0c;核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;进行性能指标对比&#xff1b;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码&#xff0c;及基于Streamlit的…

NASA数据集——1983 ——2016 年期间北美森林地点的野外地块特征数据、衍生的地上和地下燃烧碳以及获取的火灾气象指数(FWI)

文件修订日期&#xff1a;2022-05-04 数据集版本: 1 简介 该数据集综合了 1983 年至 2016 年期间美国阿拉斯加、西北地区和加拿大萨斯喀彻温省被烧毁的北方森林地点的野外地块特征数据、衍生的地上和地下燃烧碳以及获取的火灾气象指数&#xff08;FWI&#xff09;系统组件。…

基于 Quartz.NET 可视化任务调度平台 QuartzUI

一、简介 QuartzUI 是基于 Quartz.NET3.0 的定时任务 Web 可视化管理&#xff0c;Docker 打包开箱即用、内置 SQLite 持久化、语言无关、业务代码零污染、支持 RESTful 风格接口、傻瓜式配置、异常请求邮件通知等。 二、部署 QuartzUI 从 2022 年到现在没有提交记录&#xf…

计算机网络:局域网的数据链路层

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

SQLyog连接数据库8.0版本解析错误问题解决方案

问题描述&#xff1a; 解决方案&#xff1a; alter userrootlocalhostidentified with mysql_native_password by 密码; 再次连接就可以了。

Autodesk AutoCAD 2025 (macOS, Windows) - 自动计算机辅助设计软件

Autodesk AutoCAD 2025 (macOS, Windows) - 自动计算机辅助设计软件 AutoCAD 2024 开始原生支持 Apple Silicon&#xff0c;性能提升至 2 倍 请访问原文链接&#xff1a;https://sysin.org/blog/autodesk-autocad/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…

Express框架搭建项目 node.js

文章目录 引言Express框架介绍express安装环境准备写一个简单的项目展示 文章总结 引言 Express是一个基于Node.js平台的轻量级Web应用框架&#xff0c;它提供了简洁的API和丰富的功能&#xff0c;使得开发者能够快速地构建Web服务器和API。本文将带领大家从零开始&#xff0c…

【初阶数据结构】——leetcode:160. 相交链表

文章目录 1. 题目介绍2. 思路1&#xff1a;暴力求解算法思想代码实现 3. 思路2&#xff1a;快慢指针算法思想代码实现 1. 题目介绍 链接: link 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&…

文件批量重命名管理,一键将图片的名称进行统一重命名,高效管理文件

在数字时代&#xff0c;我们的生活中充满了各种文件&#xff0c;特别是图片文件。随着时间的推移&#xff0c;我们可能会遇到这样的问题&#xff1a;文件命名不规范&#xff0c;难以快速找到需要的图片。这时&#xff0c;一款强大的文件批量重命名管理工具就显得尤为重要。 首…

简约好用的TCPUDP小工具

csdn下载地址&#xff1a; https://download.csdn.net/download/a876106354/89077745

RUST语言流控制语句使用示例

1.判断语句 单条件判断: let mut x128;//声明一个32位整数x512;//修改变量原来的值为新值//如果 ... 否则//判断变量x是否大于256if x>256 {println!("x>256,x{}",x);}else {println!("x<256,x{}",x);}let is_ok:bool true;//rust中不用()if i…

前端三剑客 —— CSS (第三节)

目录 上节回顾&#xff1a; 1.CSS使用有以下几种样式; 2.选择器 1.基本选择器 2.包含选择器 3.属性选择器 [] 4.伪类选择器 &#xff1a; 5.伪元素选择器 ::before :after 3.常见样式的使用 常见样式参考表 一些特殊样式 媒体查询 自定义字体 变换效果 translate&…

2024年湖北中级职称报名时间是什么时候呢?

甘建二十年耕耘职称&#xff0c;关于职称大小事都了解 2024年湖北部分地区职称报名都已经结束了&#xff0c;恩施、十堰、黄冈、黄石、东湖高新上半年、襄阳国企事业单位和副高职称&#xff0c;这些地方的报名都截止了&#xff0c;一年一次&#xff0c;错过了有的没有第二次的话…

基于python的matplotlib库绘制折线图

代码 import matplotlib.pyplot as plt# New data for CIDEr metric beam_sizes [1, 3, 5, 7] CIDEr_new [35.2, 35.6, 38.1, 37.6]# Creating the plot for CIDEr vs Beam Size with the updated data plt.figure(figsize(10, 6)) plt.plot(beam_sizes, CIDEr_new, marker^…

pygame三角形重心坐标填充 沿x轴旋转

import pygame from pygame.locals import * import sys import math# 初始化Pygame pygame.init()# 设置窗口大小 width, height 800, 600 screen pygame.display.set_mode((width, height)) pygame.display.set_caption(3D Triangle Fill with Barycentric Coordinates)# 定…

Samba 总是需要输入网络凭证

输入网络凭证&#xff1a; 用户名是 cat /etc/samba/smb.conf&#xff0c;查看 valid users mxw 为用户名。而不是其他账号名或者用户名&#xff0c;更不是登录计算机时的计算机名&#xff1b; 密码是 需要记住安装samba服务器时&#xff0c;自己设置的password&#xff1…

鸿蒙南向开发案例:【智能养花机】

样例简介 智能养花机通过感知花卉、盆栽等植宠生长环境的温度、湿度信息&#xff0c;适时为它们补充水分。在连接网络后&#xff0c;配合数字管家应用&#xff0c;用户可远程进行浇水操作。用户还可在应用中设定日程&#xff0c;有计划的按日、按周进行浇水。在日程中用户可添…

YooAssets 使用相关

## 使用 YooAssets 动态加载原生文件时候 > 原生文件&#xff1a;txt&#xff1b;json&#xff1b;等需要直接保存文件内string字符的文件 需要将打包方式设置成为&#xff0c;PackRawFile 并且加载时候使用 API &#xff1a; YooAssets.LoadRawFileSync()YooAssets.LoadRa…

SpringBoot3入门

本文用于SpringBoot3入门。可以实现在浏览器地址栏输入localhost:8080/hello显示字符串hello world ~ 创建Maven工程 创建springboot项目。Jdk版本选17及以上&#xff0c;java选17及以上版本。打包方式选jar。因为当前工程内部已经内嵌了tomcat&#xff0c;就不用另外打包成w…