面向对象三大特征——封装

目录

1. 封装概述(封装与隐藏)

2. private关键字

3. Getter & Setter方法

4. 变量访问原则和this关键字

5. 构造方法

5.1 构造方法概述

5.2 构造方法和set方法的比较

6. 静态

6.1 静态概述

6.2 静态效果

6.3 静态变量和非静态变量的区别

6.4 工具类

7. 代码块

7.1 概述

7.2 局部代码块

7.3 构造代码块

7.4 静态代码块


1. 封装概述(封装与隐藏)

封装:隐藏事物的属性和实现细节,对外提供公共的访问方式。

为什么需要封装?封装的作用和含义?

  • 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗?有必要碰电动机吗?

  • 我要开车,...

我们程序设计追求“高内聚,低耦合”。

  • 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;

  • 低耦合 :仅对外暴露少量的方法用于使用。

封装性的设计思想

隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露 的暴露出来。这就是封装性的设计思想。

封装的好处:

  • 隐藏了事物的实现细节

  • 提高了代码的复用性

  • 提高了安全性

封装的原则:

  • 隐藏事物的属性

  • 隐藏事物的实现细节

  • 对外提供公共的访问方式

  • 代码体会:

public class Animal {String name;int legs;
​void move() {System.out.println("我叫" + name + ",我用" + legs + "条腿跑步!");}
}
​
public class AnimalTest {public static void main(String[] args) {Animal pig = new Animal();pig.name = "佩奇";pig.legs = 4; // 修改一下试试?pig.move();}
}
  • 使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。

2. private关键字

  • 含义:私有的

  • 可以修饰的内容:

    • 修饰成员变量

    • 修饰成员方法

    • 修饰构造方法

    • 修饰内部类

  • 修饰之后的效果:被private修饰的成员,只能在本类中被访问。

  • 注意事项:private只是封装的一种体现形式,封装还可以使用其他的修饰符来完成。

  • 示例:

    public class Animal {private String name;private int legs;
    ​void move() {System.out.println("我叫" + name + ",我用" + legs + "条腿跑步!");}
    }

3. Getter & Setter方法

  • 当属性被私有之后,外界无法直接访问,所以需要提供公共的访问方式,让外界可以间接的访问属性。对于当前类,就可以控制外界访问属性的方式。(我让你怎么访问,你就只能怎么访问)

  • 一般提供get方法,获取成员变量的值;提供set方法,设置成员变量的值。

  • 示例:

    public class Animal {private String name;private int legs;
    ​public String getName() {return name;}
    ​public int getLegs() {return legs;}
    ​public void setName(String n) {name = n;}public void setLegs(int l) {if (l >= 0 && l % 2 == 0) {legs = l;}}
    ​public void move() {System.out.println("我叫" + name + ",我用" + legs + "条腿跑步!");}
    }
    ​
    //*********************************************
    ​
    public class AnimalTest {public static void main(String[] args) {Animal pig = new Animal();pig.setName("佩奇");pig.setLegs(-3);pig.move();}
    }
  • 以上是封装性的体现之一,但是它并不等同于封装性!!!这点需要牢记,关于封装性的体现还有其他方面等等。比如我们将某个方法添加上private关键字,那么该方法只作为内部使用,并不会对外暴露。你是好人并不等同于你真的好!

封装性的体现,需要权限修饰符来配合。

  • Java规定了4种权限(从小到大排列):private、缺省、protected、public

  • 4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类

  • 对于class的权限修饰只可以用public和default(缺省), public类可以在任意地方被访问,default类只可以被同一个包内部的类访问。

  • 开心一笑

A man and woman are in a computer programming lecture. The man touches the woman's hand.
"Hey!" she says. "Those are private!"
The man says, "But we're in the same class!"

4. 变量访问原则和this关键字

  • 对于先前标识符的使用我们还是希望可以见明知意:我们将setName与setLegs方法中的形参都变成name和legs,我们发现方法体中的赋值出现了问题。产生问题的原因就是因为变量的访问机制。

  • 变量访问原则:

    • 就近原则:当在访问某个变量名称的时候,会先寻找最近的该变量名称的定义,如果寻找到了,就使用该变量,如果没有找到,才到更远的位置寻找该变量名称的定义。

    • 当局部变量和成员变量同名的时候,一定是先使用局部位置定义的变量,如果没有,才会使用成员位置定义的变量。

  • this关键字:

    • 表示当前类型当前对象的引用:哪个来调用this所在的方法,this就代表哪个对象

      • 作用:用于区分局部变量和成员变量同名的情况。使用this.属性名称的一定是成员变量,没有使用this.的变量,根据就近原则来确定使用哪个变量。

    • 示例:

      public class Animal {private String name;private int legs;
      ​public String getName() {return name;}
      ​public int getLegs() {return legs;}
      ​public void setName(String name) {this.name = name;}
      ​public void setLegs(int legs) {if (legs >= 0 && legs % 2 == 0) {this.legs = legs;}}
      ​public void move() {System.out.println("我叫" + name + ",我用" + legs + "条腿跑步!");}
      }/** this关键字的使用* 1.this可以用来修饰:属性、方法、构造器** 2.this修饰属性和方法:*   this理解为当前对象或者当前正在创建的对象**   2.1 在类的方法中,我们可以使用"this.属性"或者"this.方法"的形式,调用当前对象的属性或者方法。*   但是,通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须*   显式的使用"this.变量"的方式,表明此变量是属性,而非形参。**  2.2 在类的构造器中,我们可以使用"this.属性"或者"this.方法"的形式,调用当前正在创建对象的属性或者方               法。*   但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须*   显式的使用"this.变量"的方式,表明此变量是属性,而非形参。* */

5. 构造方法

5.1 构造方法概述

  • 构造方法:构造函数,构造器,Constructor

  • 作用:用于给对象中的成员变量赋值。因为在创建对象的同时,JVM会自动调用构造方法,等对象创建完成的时候,对象中的成员变量就已经有指定的值了。

  • 语法结构:

    修饰符 方法名称(参数列表) {方法体
    }
  • 构造方法说明:

    • 构造方法的方法名称,必须和类名一模一样,连大小写都一样

    • 构造方法没有返回值类型,连void也没有

    • 构造方法没有return语句,如果一定需要return语句,就写一个return;return后面不能跟内容,加return没有实际的意义

    • 构造方法不需要手动调用,由JVM在创建对象的时候自动调用

    • 对象本身不能调用构造方法

    • 构造方法只调用一次

  • 示例:

    public class Person {private String name;private int age;private String gender;
    ​public Person() {System.out.println("我被执行了");}
    }
    .......public class PersonTest {public static void main(String[] args) {Person person = new Person();}
    }
    // 在创建对象的同时,会自动调用构造方法
  • 注意事项:

    • 构造方法可以是有参数的,也可以是没有参数的。

      • 如果是没有参数的构造方法,外界无需传入任何的参数值,只能给成员变量赋固定值或者不赋值。

      • 如果是有参数的构造方法,外界在调用构造方法的时候,需要传入实际的参数值,通常用于赋值给成员变量。

    • 如果在类中没有定义任何的构造方法,那么系统会自动提供一个空参构造(空实现)。

    • 如果在类中手动定义了一个构造方法(无论是空参还是有参),系统都不再会提供任何的构造方法。

    • 构造方法的重载:构造方法都在同一个类中,构造方法的方法名称都和类名一致,参数列表不同,没有返回值类型,一般在类中,既需要空参构造,也需要有参构造,都手动定义出来。

    • 示例:

        public class Person {private String name;private int age;private String gender;
      ​public Person(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}
      ​public Person() {}
      ​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 String getGender() {return gender;}
      ​public void setGender(String gender) {this.gender = gender;}
      ​@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}
      }
      ​
      public class PersonTest {public static void main(String[] args) {Person person = new Person("zhangsan", 18, "男");System.out.println(person);}
      }/*****************************************************/
      我们也可以给set方法进行改造,让它返回对应的类型,改造方式如下:
      public Person setName(String name) {this.name = name;return this;}
      ​public Person setAge(int age) {this.age = age;return this;}
      ​public Person setGender(String gender) {this.gender = gender;return this;}创建对象时可以使用链式编程的方式Person person = new Person().setName("lisi").setAge(20).setGender("男");

5.2 构造方法和set方法的比较

  • 共同点:构造方法和set方法都是用于给成员变量赋值。不希望外界直接访问私有成员变量,通过构造方法或者set方法,间接的访问私有变量。

  • 区别:

    • 构造方法:构造方法是在创建对象的同时,由JVM自动调用执行,用于给属性赋值,只能执行一次。

    • set方法:set方法是在创建对象之后,由对象手动调用执行,用于给属性修改值,可以调用多次。

  • 使用场景比较:

    • 构造方法:只能在创建对象的时候被自动调用一次,代码更加简洁。一旦对象创建成功,就不能继续使用构造方法修改成员变量的值。

    • set方法:一般set方法使用更加灵活,使用更加频繁。

  • 总结:属性赋值的先后顺序

    • 默认初始化

    • 显示初始化

    • 构造器初始化

    • 通过"对象.方法"或者"对象.属性"的方式,赋值

    • 最终结果由最后执行的方式决定

6. 静态

6.1 静态概述

  • 静态:static关键字,静态、静止的。静态变量不会随着对象的变化而变化。

  • 加载时机:

    • 随着类的加载而加载。

    • 静态变量随着类的加载进方法区,就直接在静态区给开辟了存储静态变量的内存空间。

  • 静态变量优先于对象而存在。

  • 静态变量被所有该类对象所共享。

  • 代码层面:可以使用类名直接调用,不需要使用对象名称。在不创建对象的前提下,仍然可以使用这个静态变量。

  • 强烈建议使用类名来访问。

6.2 静态效果

  • 不使用静态:

    • 现象:如果某个类型的所有对象,都具有一个相同的属性值,比如2个对象的country都是中国; 那么这个属性值就没有必要在所有对象中,都存储一份。

    • 缺点:浪费内存空间;维护难度大,一旦需要修改,就得修改所有的对象。

    • 示例:

      public class StaticDemo {private String username;private String country;
      ​public String getUsername() {return username;}
      ​public void setUsername(String username) {this.username = username;}
      ​public String getCountry() {return country;}
      ​public void setCountry(String country) {this.country = country;}
      ​public static void main(String[] args) {StaticDemo st1 = new StaticDemo();st1.setUsername("zs");st1.setCountry("中国");StaticDemo st2 = new StaticDemo();st1.setUsername("lisi");st1.setCountry("中国");
      ​st1.setCountry("东三省");st2.setCountry("东三省");}
      }
  • 使用静态:

    • 现象:如果某个类型的所有对象,都具有一个相同的属性值,那么就在这个属性的定 义上,加一个static静态关键字。让该变量存储在方法区字节码的静态区中,避免了所有对象都存储相 同数据的问题,节省了内存空间,将来维护容易(只需要修改一次)。

    • 示例:

      public class StaticDemo {private String username;private static String country;
      ​public String getUsername() {return username;}
      ​public void setUsername(String username) {this.username = username;}
      ​public static String getCountry() {return country;}
      ​public static void setCountry(String country) {StaticDemo.country = country;}
      ​public static void main(String[] args) {StaticDemo st1 = new StaticDemo();st1.setUsername("zs");st1.setCountry("中国");StaticDemo st2 = new StaticDemo();st1.setUsername("lisi");System.out.println(st2.getCountry());st2.setCountry("东三省");System.out.println(st1.getCountry());}
      }
  • 注意事项:

    • 静态方法:在方法声明上,加上了static关键字的方法,就是静态方法。

    • 静态方法不能访问非静态的变量:静态方法本身可以在没有创建对象的时候调用;非静态的变量只有在对象创建之后才存在。如果静态方法可以访问非静态的变量,那么就相当于在对象创建之前,就访问了对象创建之后的数据。明显不合理。

    • 静态方法不能访问非静态的方法:静态方法可以在没有创建对象的时候调用;非静态的方法可以访问非静态的变量。如果静态方法可以访问非静态的方法,就相当于静态方法间接的访问了非静态的变量,和第2点矛盾。

    • 静态方法中不能存在this关键字:this关键字表示本类当前对象。静态方法可以在对象创建之前调用。如果静态方法可以访问 this关键字,相当于在创建对象之前,就使用了对象本身。矛盾。

    • 总结:静态资源不能访问非静态资源

6.3 静态变量和非静态变量的区别

  • 概念上,所属不同:

    • 非静态变量属于对象。

    • 静态变量属于类,类变量。

  • 内存空间不同,存储位置不同:

    • 非静态变量属于对象,所以存储在堆内存中。

    • 静态变量属于类,存储在方法区的静态区中。

  • 内存时间不同,生命周期不同:

    • 非静态变量属于对象,所以生命周期和对象相同,随着对象的创建而存在,随着对象的消失而消失。

    • 静态变量属于类,所以生命周期和类相同,随着类的加载。

  • 访问方式不同:

    • 非静态变量只能使用对象名访问。

    • 静态变量既可以使用对象访问,也可以通过类名访问(强烈建议使用类名访问):

      • 类名.静态变量名

      • 类名.静态方法名()

6.4 工具类

  • 工具类:在一个类中,没有维护什么数据,没有任何的成员变量,相当于是一个工具。类中就都是一些静态方法,快速的解决一些常见的问题。

  • 方法都是静态的,不需要创建对象;创建对象会浪费系统资源。希望控制不让创建对象(方式:使用构造方法私有化)。

  • 示例:数组工具类

    public class ArraysUtils {//    构造方法私有化,保证类不会被创建对象private ArraysUtils() {}
    ​// 1、循环打印数组public static void print(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + ",");}}
    ​// 2、循环打印数组,一行打印指定个数的元素public static void print(int[] arr, int number) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + ",");if ((i + 1) % number == 0) {// 换一行System.out.println();}}}
    ​// 3、将数组转成[元素1,元素2...]这种格式的字符串public static String formatPrint(int[] arr) {if (arr == null)return "null";// 如果iMax是-1 意味着数组长度是0int iMax = arr.length - 1;if (iMax == -1)return "数组长度为0";StringBuilder b = new StringBuilder();b.append('[');// 在最前方追加一个[for (int i = 0; ; i++) {b.append(arr[i]);// 满足条件 就退出if (i == iMax) {return b.append(']').toString();}b.append(", ");}}
    ​// 4、将数组冒泡\或者其他算法排序(直接将原数组排序)public static void sort(int[] arr) {for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if (arr[j] > arr[j + 1]) {int desk = arr[j];arr[j] = arr[j + 1];arr[j + 1] = desk;}}}}
    ​// 5、将数组冒泡\或者其他算法排序(不允许排形参的数组,需要直接返回一个排好序的新数组)public static int[] sortNew(int[] arr) {int arrNew[] = new int[arr.length];// 把源数组 内容赋值一份给 arrNew// arrNew = Arrays.copyOf(arr, arr.length);for (int i = 0; i < arrNew.length; i++) {arrNew[i] = arr[i];}
    ​for (int i = 0; i < arrNew.length - 1; i++) {for (int j = 0; j < arrNew.length - 1 - i; j++) {if (arrNew[j] > arrNew[j + 1]) {int desk = arrNew[j];arrNew[j] = arrNew[j + 1];arrNew[j + 1] = desk;}}}return arrNew;}
    ​// 6、比较两个数组的所有元素是否完全一致public static boolean isEquals(int[] arr1, int[] arr2) {// 地址相同 里面的数据肯定相同if (arr1 == arr2)return true;if (arr1 == null || arr2 == null)return false;
    ​int length = arr1.length;if (arr2.length != length)return false;
    ​for (int i = 0; i < length; i++)if (arr1[i] != arr2[i])return false;
    ​return true;}
    ​// 7、计算数组的平均值public static double avg(int[] arr) {double sum = 0;for (int i = 0; i < arr.length; i++) {sum += arr[i];}return sum / arr.length;}
    ​// 8、计算数组的最大值public static int max(int[] arr) {// 数组第一个 为最大值int maxnumber = arr[0];for (int i = 1; i < arr.length; i++) {if (maxnumber < arr[i]) {maxnumber = arr[i];}}return maxnumber;}
    ​// 9、计算数组的最小值public static int min(int[] arr) {// 数组第一个 为最小值int minnumber = arr[0];for (int i = 0; i < arr.length; i++) {if (minnumber > arr[i]) {minnumber = arr[i];}}return minnumber;}
    ​// 10、将一个数组的所有元素都反转(比如{5,4,8}变成{8,4,5})public static int[] reverse(int[] arr) {int[] arrNew = new int[arr.length];for (int x = 0; x < arr.length; x++) {arrNew[x] = arr[arr.length - 1 - x];}return arrNew;}
    ​// 11、判断一个指定的数值在数组中是否存在public static boolean isExits(int[] arr, int number) {boolean isTrue = false;for (int i = 0; i < arr.length; i++) {if (arr[i] == number) {return true;}}// 如果不存在return false;}
    }

7. 代码块

7.1 概述

  • 使用大括号包起来的一段代码。放在不同的位置,有不同的名称,有不同的作用,有不同的执行时机。

  • 分类:

    • 局部代码块

    • 构造代码块

    • 静态代码块

    • 同步代码块(多线程中会遇到)

7.2 局部代码块

  • 格式:使用大括号包起来的一段代码

  • 位置:方法中

  • 作用:

    • 限定变量的生命周期,作用域只是在大括号内部。

    • 在局部代码块中【声明】的变量,只能在局部代码块的范围内使用,一旦出了局部代码块的大括号,变量就不能继续使用了。

    • 某个变量一旦不能使用了,就会被回收,节省内存空间。

  • 注意事项:

    • 局部代码块内声明的变量,会减少变量的生命周期,局部代码块执行完毕后,就无法继续使用变量。

    • 局部代码块外声明的变量,局部代码块执行完毕后,仍可以继续使用变量。

  • 示例:

    public class Demo {public static void main(String[] args) {int a = 123;{int b = 456;System.out.println(a);System.out.println(b);}System.out.println(a);}
    }

7.3 构造代码块

  • 格式:使用大括号包起来的一段代码

  • 位置:类中方法外

  • 作用:

    • 用于给成员变量初始化赋值。

    • 在创建对象时执行部分操作。

  • 构造代码块的执行说明:

    • 在创建对象的时候执行,由 JVM 默认调用,用于给对象的属性赋值。

    • 在构造方法执行之前执行。

    • 任意一个构造方法执行之前,都会执行一次构造代码块的内容。

    • 如果每个构造方法都会执行的内容,请提取到构造代码块中执行。

  • 示例:

    public class Demo {{System.out.println("我是一个构造代码块");}
    ​public static void main(String[] args) {Demo demo = new Demo();}
    }

7.4 静态代码块

  • 格式:

    static {静态代码块的内容
    }
  • 位置:类中方法外

  • 作用:

    • 用于给静态的成员变量初始化赋值

    • 用于执行那些只需要执行一次的代码,例如驱动加载等

  • 执行特点:

    • 随着类的加载而执行

    • 类只加载一次,所以静态代码块只执行一次

    • 执行的时机最早:早于所有的对象相关内容,比main方法执行的早

  • 示例:

    public class Demo {static {System.out.println("说我是静态代码块");}
    ​{System.out.println("我是构造代码块");}
    ​public static void main(String[] args) {System.out.println("我是main方法");Demo demo = new Demo();}
    }

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

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

相关文章

win11 CUDA(12.3) + cuDNN(12.x) 卸载

win11 CUDA&#xff08;12.3&#xff09; cuDNN&#xff08;12.x&#xff09;卸载 信息介绍卸载 信息介绍 本文是对应 win11RTX4070Ti 安装 CUDA cuDNN&#xff08;图文教程&#xff09; 的卸载 卸载 控制面板 --> 程序 --> 卸载程序 卸载掉图中红框内的&#xff0c…

reinforce 跑 CartPole-v1

gym版本是0.26.1 CartPole-v1的详细信息&#xff0c;点链接里看就行了。 修改了下动手深度强化学习对应的代码。 然后这里 J ( θ ) J(\theta) J(θ)梯度上升更新的公式是用的不严谨的&#xff0c;这个和王树森书里讲的严谨公式有点区别。 代码 import gym import torch from …

Android 11 适配——整理总结篇

背景 > 经过检测&#xff0c;我们识别到您的应用&#xff0c;目前未适配安卓11&#xff08;API30&#xff09;&#xff0c;请您关注适配截止时间&#xff0c;尽快开展适配工作&#xff0c;避免影响应用正常发布和经营。 > targetSdkVersion30 升级适配工作参考文档&am…

从零开发短视频电商 Jmeter压测示例模板详解(无认证场景)

文章目录 添加线程组添加定时器添加HTTP请求默认值添加HTTP头管理添加HTTP请求添加结果断言响应断言 Response AssertionJSON断言 JSON Assertion持续时间断言 Duration Assertion 添加察看结果树添加聚合报告添加表格察看结果参考 以压测百度搜索为例 https://www.baidu.com/s…

class066 一维动态规划【算法】

class066 一维动态规划 算法讲解066【必备】从递归入手一维动态规划 code1 509斐波那契数列 // 斐波那契数 // 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 // 该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。…

kotlin - ViewBinding

前言 为什么用ViewBinding&#xff0c;而不用findViewById()&#xff0c;这个有很多优秀的博主都做了讲解&#xff0c;就不再列出了。 可参考下列博主的文章&#xff1a; kotlin ViewBinding的使用 文章里也给出了如何在gradle中做出相应的配置。 &#xff08;我建议先看这位博…

【LeetCode热题100】【滑动窗口】无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为无…

Redis,什么是缓存穿透?怎么解决?

Redis&#xff0c;什么是缓存穿透&#xff1f;怎么解决&#xff1f; 1、缓存穿透 一般的缓存系统&#xff0c;都是按照key去缓存查询&#xff0c;如果不存在对用的value&#xff0c;就应该去后端系统查找&#xff08;比如DB数据库&#xff09;。一些恶意的请求会故意查询不存在…

不想写大量 if 判断?试试用规则执行器优化,就很丝滑!

近日在公司领到一个小需求&#xff0c;需要对之前已有的试用用户申请规则进行拓展。我们的场景大概如下所示: if (是否海外用户) {return false; }if (刷单用户) {return false; }if (未付费用户 && 不再服务时段) {return false }if (转介绍用户 || 付费用户 || 内推…

16ASM 分段和机器码

8086CPU存储分段管理 问题1&#xff1a;8086是16位cpu&#xff0c;最多可访问&#xff08;寻址&#xff09;多大内存&#xff1f; 运算器一次最多处理16位的数据。地址寄存器的最大宽度为16位。访问的最大内存为&#xff1a;216 64K 即 0000 - FFFF。 问题2&#xff1a;808…

WIFI直连(Wi-Fi P2P)

一、概述 Wifi peer-to-peer&#xff08;也称Wifi-Direct&#xff09;是Wifi联盟推出的一项基于原来WIfi技术的可以让设备与设备间直接连接的技术&#xff0c;使用户不需要借助局域网或者AP&#xff08;Access Point&#xff09;就可以进行一对一或一对多通信。这种技术的应用…

计算机毕业设计 SpringBoot的乐乐农产品销售系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

Xmanager

什么是 XManager Xmanager 是市场上领先的 PC X 服务器&#xff0c;可将X应用程序的强大功能带入 Windows 环境。 提供了强大的会话管理控制台&#xff0c;易于使用的 X 应用程序启动器&#xff0c;X 服务器配置文件管理工具&#xff0c;SSH 模块和高性能 PC X 服务器。 Xman…

javaScript(六):DOM操作

文章目录 1、DOM介绍2、DOM&#xff1a;获取Element对象3、DOM&#xff1a;事件监听3.1、事件介绍3.2、常见事件3.3、设置事件的两种方式3.4、事件案例 1、DOM介绍 概念 Document Object Model &#xff0c;文档对象模型 将标记语言的各个组成部分封装为对应的对象&#xff1a…

Realme X7 Pro Root 刷机教程

Realme X7 Pro 刷机教程 Just For Fun&#xff0c;最近倒腾了下Realme X7 Pro 刷root。此博客为个人记录刷机过程&#xff0c;如有机友跟随本教程操作&#xff0c;请谨慎操作&#xff01;&#xff01;&#xff01; 以下教程真针对Realme X7 Pro&#xff0c;其他版本方法未知&…

【Flutter】vs2022上开发flutter

在vs上开发flutter&#xff0c;结果扩展仓库上没办法找到Dart&#xff0c;Flutter。 在 这 搜索Dart时也无法找到插件。 最后发现是安装工具出错了 安装了 开发需要的是

从线性回归到神经网络

目录 一、线性回归关键思想 1、线性模型 2、基础优化算法 二、线性回归的从零开始实现 1、生成数据集 2、读取数据集 3、初始化模型参数 4、定义模型 5、定义损失函数 6、定义优化算法 7、训练 三、线性回归的简洁实现 1、生成数据集 2、读取数据集 3、定义模型…

论文代码阅读:TGN模型训练阶段代码理解

文章目录 [toc] TGN模型训练阶段代码理解论文信息代码过程手绘代码训练过程compute_temporal_embeddingsupdate_memoryget_raw_messagesget_updated_memoryself.message_aggregator.aggregateself.memory_updater.get_updated_memoryMemoryget_embedding_moduleGraphAttentionE…

【AIGC】Midjourney高级进阶版

Midjourney 真是越玩越上头&#xff0c;真是给它的想象力跪了~ 研究了官方API&#xff0c;出一个进阶版教程 命令 旨在介绍Midjourney在Discord频道中的文本框中支持的指令。 1&#xff09;shorten 简化Prompt 该指令可以将输入的Prompt为模型可以理解的语言。模型理解语言…

【Linux】如何对文本文件进行有条件地划分?——cut命令

cut 命令可以根据一个指定的标记&#xff08;默认是 tab&#xff09;来为文本划分列&#xff0c;然后将此列显示。 例如想要显示 passwd 文件的第一列可以使用以下命令&#xff1a;cut –f 1 –d : /etc/passwd cut&#xff1a;用于从文件的每一行中提取部分内容的命令。-f 1&…