Java_面向对象

news2024/11/13 22:50:30

Java_面向对象

1.面向对象概述

面向对象是一种符合人类思想习惯的编程思想。显示生活中存在各种形态的不同事物,这些食物存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的关系,这种思想就是面向对象的编程思想。使用面向对象思想的编程语言有:Java、Python、PHP。。。

​ 与之相对的是面向过程的编程思想,面向过程就是分析出解决问题的所需步骤,然后用函数把这些步骤一一实现,使用的时候依次调用就行了。典型的代表是C语言。

​ 面向对象的三大特征:

  • **封装:**将面向对象的核心思想(对象的属性和行为)封装起来,不让外界知道其具体细节;
  • **继承:**类与类之间的关系,通过继承,可以通过无需再编写新的类的情况下,对原有的类的功能进行扩展;
  • 多态:在一个类中定义的属性和行为被其他类继承后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一个方法所呈现出的多种不同行为特征

image-20230213152446030

2.Java中的类与对象

​ **说明:**面向对象的编程思想,力图让程序中对事物的描述与该事物在现实中的形态保持一致。为了实现这一点,面向对象思想中提出了两个概念----类与对象。

  • **类:**是一类事物的描述,包含属性和行为。如动物类、汽车类…
  • **对象:**某一类事物的具体体现。如动物类的🐱、🐕、🐖、🐏等,汽车类的🚚、🚆、🚕、🚝等。

2.1.类

​ 面向对象的核心思想是对象,但要创建对象,首先需要定义一个类。类是对象的抽象,用于描述一组对象的共同行为特征。以面向对象的思想,就可以将某一类中共同的特征和行为封装起来,把共同的特征作为类的属性(也叫成员变量),把共同行为作为类的方法(也叫成员方法)。

  • 定义类:

image-20230213153631448

public class 类名 {
    // 成员变量
    // 成员方法
}
public class Person {
    
    // 成员变量:描述类的属性
    String name; // 人的姓名
    int age; // 人的年龄
    
    /*
    * 成员方法:
    *   格式:权限修饰符 返回值类型  方法名(args...) {方法体 return 返回值}
    * */
    // 吃饭的方法
    public void eat(String food) {
        System.out.println(name+ "正在吃" + food);
    }
    // 睡觉的方法
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

2.2.对象

​ 对象是类的具体体现。要使用一个类,必须通过对象来实现,创建对象的语法格式为:

类名 对象名 = new  类名();

Person p = new Person();
/*
* 通过Person类创建对象
* */
public class Object {

    public static void main(String[] args) {
        // 1.创建对象
        Person p = new Person();
        
        // 2.使用成员变量--对象名.变量名
        System.out.println(p.name); // null
        System.out.println(p.age); // 0
        // 赋值
        p.name = "张三";
        p.age = 20;
        System.out.println("========");
        
        // 3.使用成员方法--对象名.方法名()
        p.eat("西瓜");
        p.sleep();
    }
}

其对象的内存示意图为:

image-20230213204006284

代码执行流程为:

  1. Person类和Object类的字节码文件加载到方法区;
  2. 找到主方法main()进入到栈空间,并创建对象p
  3. 一切new关键字的对象进入堆内存,并引入属性和方法;
  4. 先执行eat()方法,执行完毕被销毁,再执行sleep()方法,执行完毕也随之销毁;
  5. main()方法随着程序执行完成,也随之销毁。

注意:

  • 程序执行完毕,垃圾将会被回收。回收的条件是引用计数器是否为0。
  • 方法进入栈中采用“先来后出”的方式,这一过程被称为《压栈》。

2.3.对象的比较

​ 在Java中有两种对象的比较方式,分为为“==”运算符和equals()方法,这两种方式有着本质的区别,以下面例子说明:

​ 我们创建Compare类:

public class ObjCompare {
    public static void main(String[] args) {
        // 创建两个String对象引用
        String c1 = new String("abc");
        String c2 = new String("abc");
        String c3 = c1;
        // 使用==运算符比较
        System.out.println("c2==c3的结果为:" + (c2==c3));
        // 使用equals()方法比较
        System.out.println("c2.equals(c3)的结果为:" + (c2.equals(c3)));
    }
}

​ 运行结果为:

image-20230215211711191

​ 从上述运行结果中可以看出,“”运算符和equals()方法比较的结果是不同的。**equals()方法是String类中的方法,它用于比较两个对象引用所指的内容是否相等;而“”运算符比较的是两个对象引用的地址是否相等。**由于c1和c2是两个不同对象引用,两者在内存中的位置不同,而String c3 = c1;语句将c1的引用赋给c3,所以c1和c3这两个对象的引用是相等的,也就是打印c1==c3将返回true。它们的内存引用如下图:

image-20230215212805012

2.4.局部变量和成员变量

​ 在类中定义的变量为成员变量(全局变量),在方法中定义的变量为局部变量。Java遵守就近原则,谁离得近就优先使用谁。

我们在eat()方法中新增属性String name = "李四";,这时执行的是“李四正在吃xx”:

// 吃饭的方法
public void eat(String food) {
    String name = "李四";
    System.out.println(name+ "正在吃" + food);
  }

image-20230213205402508

成员变量和局部变量的区别:

  1. 定义位置:
    • 成员变量:定义在类中,方法外
    • 局部变量:定义在方法内部
  2. 内存中的位置:
    • 成员变量:在堆内存中
    • 局部变量:在栈内存中
  3. 声明周期的区别:
    • 成员变量:随着对象的创建而创建,随着对象的消失而消失
    • 局部变量:随着方法的调用而创建,随着方法的消失而消失
  4. 默认初始化值的区别:
    • 成员变量:有默认初始化值
    • 局部变量:没有默认初始化值,使用之前必须赋值

2.5.访问修饰符

​ 在Java中,针对类和对象提供了四种访问级别,分别是privatedefaultprotectedpublic。它们的访问控制级别由小到大为:

image-20230215204422104

四种访问级别说明:

  • **private(当前类访问级别):**如果类的成员被private访问控制符来修饰,则这个成员只能被该类的其他成员访问,其他类无法直接访问。类的良好封装就是通过private来实现的。
  • **default(包访问级别):**如果一个类或者类的成员不适用任何访问控制符修饰,则称它为默认访问控制级别,这个类或者类的成员只能被本包中的其他类访问。
  • **protected(子类访问级别):**如果一个类成员被protected访问控制符修饰,那么这个成员就能被同一包下的其他类访问,也能被不同包下的该类的子类访问。
  • **public(公共访问级别):**这是一个最宽松的访问控制级别,如果一个类或者类的成员被public访问控制符修饰,那么这个类或者类的成员能被所有的类访问,不过访问类和被访问类是否在同一个包中。

3.类的封装

​ 封装是面向对象的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装思想。例如,用户使用计算机,只需要使用手指敲击键盘就可以实现一些功能,无需知道计算机内部是如何工作的。即使知道计算机工作的原理,但在使用计算机时也并不依赖计算机工作原理这些细节。

​ 采用封装思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据。这样避免了外部操作对内部数据的影响,提高了程序的可维护性。

image-20230215214323016

​ 假如我们利用上面创建的Person类,再创建一个Demo类来测试:

public class Demo {

    public static void main(String[] args) {
        Person p = new Person();
        p.name = "张三";
        p.age = -123;
        System.out.println("姓名是:" + p.name + ",年龄是:" + p.age );
    }
}

​ 我们可以发现我们创建的这个Demo类随意设置了数据,且有些数据是不合理的。那么我们就应该封装Person类,提高代码的可维护性。使用修饰符private就可以实现对类成员的封装:

private String name; // 人的姓名
private int age; // 人的年龄

​ 经过private封装后的属性,我们看到在本类中使用是没有问题的,但在Demo类中就报错了:

image-20230215215209579image-20230215215223819

image-20230215215223819

​ 想要实现访问这两个属性,我们需要增加一个访问这两个属性的公共方法,这样Demo类就可以通过这个公共方法实现属性的访问。

// 设置值
public void setName(String n) {
    name = n;
}
// 获取值
public String getName() {
    return name;
}
// 设置值
 public void setAge(String a) {
     if (a < 0 || a > 200) {
            System.out.println("你设置的年龄不合法");
        }else {
            age = a;
        }
}
// 获取值
public String getAge() {
    return age;
}

​ 这是我们就可以在Demo类中通过getset方法就可以设置值和访问值了:

public class Demo {

    public static void main(String[] args) {
        Person p = new Person();
        // 设置值
        p.setName("张三");
        p.setAge(123);
        // 获取值
        String name = p.getName();
        int age = p.getAge();
        System.out.println("姓名是:" + name + ",年龄是:" + age );
    }
}

image-20230215220448893

4.方法的重载和递归

​ 重载就是函数或方法有相同的名称,但是参数列表不相同的情形。这样同名不同参数的函数或者参数之间,互相称之为重载。通俗理解就是省了给method重新命名了,差不多都用同一个。

​ 而递归则是因特殊业务需求,需要在函数内部调用自己的过程,这样能做到“大事化小,小事化了”。 需要注意的是,递归必须要有结束的条件,不然就会陷入无限的递归状态,永远无法结束调用。

  • 重载实例:
public class Overload {

    public static void main(String[] args) {
        int sum = getSum(20,30);
        int sum01 = getSum(20,30,40);
        System.out.println(sum);
        System.out.println(sum01);
        
    }
    /**
     * 定义求两个整数和的方法
     * 明确参数:int num01, int num02
     * 返回值:int
     * */
    public static int getSum(int num01,int num02) {
        int sum = num01 + num02;
        return sum;
    }
    /**
     * 求三个数和的方法
     * 参数:int num01,int num02,int num03
     * 返回值:int
     */
    public static int getSum(int num01,int num02,int num03) {
        int sum = num01 + num02 + num03;
        return sum;
    }
}
  • 递归实例:
public class Recursion {
    public static void main(String[] args) {
        int sum = getSum(5);
        System.out.println(sum);
    }
    /**
     * 需求:求5-1之间的数字之和
     *  5+4+3+2+1
     *  5+(4-1之间的和) + 4+(3-1之间的和)...
     */
    public static int getSum(int num) {
        if (num == 1) {
            return 1;
        }
        return num + getSum(num-1);
    }
}
image-20230216211258321

练习:递归读取指定文件夹下的文件和目录:

public class Test1 {

    public static void showDirectory(File file) {
        File[] files=file.listFiles();
        for(File a:files) {
            System.out.println(a.getAbsolutePath());
            if(a.isDirectory()) {
                try{
                    showDirectory(a);
                }catch (Exception e) {
                    System.out.println(e);
                }
            }
        }
    }

    public static void main(String[] args) {
        File file=new File("D:\\");
        showDirectory(file);
    }
}

5.构造方法

​ 实例化一个对象后,如果要为这个对象中的属性赋值,则必须通过直接访问对象的属性或调用setXXX()方法的方式才可以。如果需要在实例化对象的同时就为这个对象的属性进行赋值,则可以通过构造方法来实现。

​ **构造方法:**是类的一个特殊成员,它会在类实例化对象时被自动调用。以之前的Person类为例,我们只需要在你们去添加无参构造和有参构造,就可以在实例化对象时初始化一些值。

// 无参构造
public Person() {
 }
// 有参构造
public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

​ 我们可以看到构造方法就是直接以类名作为方法名,根据参数的不同分为无参构造和有参构造。通过这两个不同的构造方法,创建出来的对象也是不同的:

Person p1 = new Person();  // 无参构造创建对象
Person p2 = new Person("张三",20); // 有参构造创建对象

​ 关于构造方法有几个注意事项:

  • 构造方法和类名一致;
  • 构造方法没有返回值类型,void也不需要写;
  • 构造方法中不能写return语句;
  • 每一个类都有一个默认的无参构造,所以可以不用手动写出来。

6.this关键字

​ 在有参构造中,我们看到了this关键字的使用,这是因为要将参数和属性进行统一命名(见名知义),保持程序的可读性,但如果没有就会产生成员变量和局部变量的命名冲突,在方法中无法访问成员变量。所以Java提供了this来指代当前对象,用于在方法中访问对象的其他成员。

7.static关键字

​ 有时候,在处理问题时需要两个类在同一个内存区域共享一个数据。例如,在球类中PI这个常量,可能除了本类需要这个常量外,在另一个圆类中也需要这个常量。这时没有必要再两个类中同时创建PI常量,因为这样系统会将两个不在同一个类中定义的常量分配到不同的内存空间中。为了解决这个问题,可以将这个常量设置未静态的。PI常量在内存中被共享的布局如图所示:

image-20230220220423476

​ 被生命static的变量、常量、方法被称为静态成员。静态成员属于类所有,区别于个别对象,可以在本类后者其他类使用类名和"."调用静态成员。语法如下:

类名.静态成员

​ 在下面代码中创建了StaticTest类,该类中的主方法调用静态成员并在控制台输出。

// 静态方法的调用
public class StaticTest {
    final static double PI = 3.1415;  // 定义静态常量
    static int id; // 定义静态变量
    
    public static void method1() {
        // do Something
    }
    
    public void method2() {
        System.out.println(StaticTest.PI);
        System.out.println(StaticTest.id);
        StaticTest.method1();
    }
}

​ 静态方法也可以通过对象"."的方式,但不推荐这种用法,以便和非静态成员分开。

​ 静态数据与静态方法的作用通常是为了提供共享数据或方法,如数学计算公式等,以static生命并实现,这样当需要使用时,直接使用类名调用这些静态成员即可。机关使用这种方式调用静态成员比较方便,但静态成员同样遵循public,private,protected修饰符的约束。

​ 在StaticTest类中创建书方法调用静态成员并输出:

public class StaticTest {
    final static double PI = 3.1415;  // 定义静态常量
    static int id; // 定义静态变量
    
    public static void method1() {
        // do Something
    }
    
    public void method2() {
        System.out.println(StaticTest.PI);
        System.out.println(StaticTest.id);
        StaticTest.method1();
    }
    public static StaticTest method3() {
        method2();  // 调用非静态方法
        return  this;
    }
}

​ 我们会发现以上代码会报错,这是因为在静态方法中调用了非静态方法和this关键字的出现,在Java中有两点规定:

  • 在静态方法中不可以使用this关键字;
  • 在静态方法中不可以直接调用非静态方法。

**注意:**在Java中规定不能将方法体内的局部变量声明为static的。例如下面代码就是错误的:

public class example{
        puclic void method() {
            static int i = 0;
        }
    }

**技巧:**如果在执行类时,希望先执行类的初始化操作,可以使用static定义一个静态区域,例如如下代码,当这段代码执行时,首先执行static块中的程序,并且只会执行一次

public class example {
        static {
            // 
        }
    }
  • 静态代码块练习:
public class Demo04 {
     static {
        System.out.println("我是静态代码块。。。");
    }
}
public class Demo05 {

    public static void main(String[] args) {
        Demo04 d = new Demo04();

        Demo04 d1 = new Demo04();
    }
}

​ 我们发现,创建对象就执行了静态代码块,且执行一次。

  • 静态变量的练习:创建Student类,有name、age、schoolName三个属性,在Demo类中分别创建三个对象,使得他们姓名、年龄不同,但学校相同,既可以使用静态变量占用一个内存:
public class Student {
    private String name; // 姓名
    private int age; // 年龄
    private String schoolName; // 大学名称

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

    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 getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }
}

public class Demo01 {
    public static void main(String[] args) {
        Student s01 = new Student();
        s01.setName("张三");
        s01.setAge(20);
        s01.setSchoolName("四川城市职业学院");
		System.out.println(s01);
        System.out.println("===========");

        Student s02 = new Student();
        s02.setName("李四");
        s02.setAge(21);
        s02.setSchoolName("四川城市职业学院");
		System.out.println(s02);
        System.out.println("===========");

        Student s03 = new Student();
        s03.setName("王五");
        s03.setAge(20);
        s03.setSchoolName("四川城市职业学院");
		System.out.println(s03);
    }
}

​ 以上代码我们发现他们三个对象都一个同一变量值为:“四川城市职业学院”,如果创建三个对象,对应在内存中也要为这个值开辟三个空间,这样浪费了内存,我们可以将schoolName声明为静态变量,这样一个对象赋值,其他对象也可以一并使用了:

// 将Student类的schoolName变为静态变量
private static String schoolName;

// 注释Demo01中s02和s03对schoolName属性的赋值
// s02.setSchoolName("四川城市职业学院");
// s03.setSchoolName("四川城市职业学院");

​ 运行发现实现了静态变量的共享:

image-20230220225503595

);
System.out.println(“===========”);

    Student s03 = new Student();
    s03.setName("王五");
    s03.setAge(20);
    s03.setSchoolName("四川城市职业学院");
	System.out.println(s03);
}

}


​	以上代码我们发现他们三个对象都一个同一变量值为:“四川城市职业学院”,如果创建三个对象,对应在内存中也要为这个值开辟三个空间,这样浪费了内存,我们可以将schoolName声明为静态变量,这样一个对象赋值,其他对象也可以一并使用了:

```java
// 将Student类的schoolName变为静态变量
private static String schoolName;

// 注释Demo01中s02和s03对schoolName属性的赋值
// s02.setSchoolName("四川城市职业学院");
// s03.setSchoolName("四川城市职业学院");

​ 运行发现实现了静态变量的共享:

[外链图片转存中…(img-p29C2KQe-1677763476620)]

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

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

相关文章

如何使用码匠连接 Redis

目录 在码匠中集成 Redis 在码匠中使用 Redis 关于码匠 Redis 是由 Salvatore Sanfilippo 用 C 语言开发的一款开源的、高性能的键值对存储数据库&#xff0c;它采用 BSD 协议&#xff0c;为了适应不同场景下的存储需求&#xff0c;提供了多种键值数据类型。到目前为止&…

汇川AM402和上位机C#ModebusTcp通讯

目录 一、测试任务 二、测试环境 三、PLC工程 1、组态配置 2、ip地址、端口号 3、全局变量定义 四、C#端Winform程序创建 1创建主界面 2、创建子窗口 3、运行生成&#xff0c;界面效果 4、Modebus协议说明 5、Modebus操作说明 六、测试 1、寄存器读测试 2、MW1300寄…

软件著作权登记申请表填错之后如何修改?软著登记官费有没有续费或年费?软件登记常见问题汇总

什么是计算机软件&#xff1f; 计算机软件是指计算机程序及其有关文档。计算机程序是指能实现一定功能的代码化指令序列&#xff0c;或者符号化语句序列。文档指用来描述程序的内容、组成、设计、功能规格、开发情况、测试结果及使用方法的文字资料和图表&#xff0c;如程序设…

centos7如何远程连接Navicat数据库?

1、登录centos7&#xff0c;启动mysql服务 [rootlocalhost ~]# systemctl start mysqld 2、设置mysql服务开机自启 [rootlocalhost ~]# systemctl enable mysqld [rootlocalhost ~]# systemctl daemon-reload 3、查看mysql服务状态 4、若未更改初始密码&#xff0c;若已更改…

4.基于Label studio的训练数据标注指南:情感分析任务观点词抽取、属性抽取

情感分析任务Label Studio使用指南 1.基于Label studio的训练数据标注指南&#xff1a;信息抽取&#xff08;实体关系抽取&#xff09;、文本分类等 2.基于Label studio的训练数据标注指南&#xff1a;&#xff08;智能文档&#xff09;文档抽取任务、PDF、表格、图片抽取标注等…

网络协议(九):应用层(域名、DNS、DHCP)

网络协议系列文章 网络协议(一)&#xff1a;基本概念、计算机之间的连接方式 网络协议(二)&#xff1a;MAC地址、IP地址、子网掩码、子网和超网 网络协议(三)&#xff1a;路由器原理及数据包传输过程 网络协议(四)&#xff1a;网络分类、ISP、上网方式、公网私网、NAT 网络…

听说你没法在 JRE 中使用 arthas?不,你可以

作者&#xff1a;卜比 本文是《容器中的 Java》系列文章之 5/n &#xff0c;欢迎关注后续连载 &#x1f603; 。 JVM如何获取当前容器的资源限制&#xff1f;——容器中的Java 1Java Agent踩坑之appendToSystemClassLoaderSearch问题——容器中的Java 2让 Java Agent 在 Drag…

SEO 如何提升网站权重?

关于SEO如何提高网站权重&#xff0c;米贸搜整理了以下内容&#xff0c;希望对大家有所帮助&#xff1a;1. 网站不能都使用收藏。有些站长&#xff0c;在网站上线之前&#xff0c;没有充分考虑&#xff0c;没有很好地定位网站&#xff0c;网站内容的来源从哪里来&#xff0c;就…

全网最详细的软件测试基础知识概述(绝密),一般人我不告诉他

目录 1、什么是软件 2、软件工程的内容 3、软件的生命周期 4、什么是软件测试 5、软件测试的方法 6、软件测试阶段有哪些任务 7、测试的原则 8、软件测试工作流程图 9、自动化测试 10、自动化测试的过程 11、自动化测试的优点 12、自动化测试技术 13、自动化测试的…

EasyExcel 实现写入多个sheet数据进excel模板并下载

目录说明说明 场景说明&#xff1a;对数据库或者其他数据源读取获取到数据&#xff0c;需要写入到excel完成下载功能&#xff0c;其中一个sheet是固定模板&#xff0c;只需要填充值&#xff0c;另一个sheet是动态的表头和数据需要填充。模板如下图&#xff0c;模板提前放在项目…

【简单DP】Children’s Queue

哈哈&#xff0c;独立做出来了&#xff0c;不错感觉这种暴力DP还是很好做的Problem - 1297 (hdu.edu.cn)题意&#xff1a;思路&#xff1a;写了这么多DP&#xff0c;我认识到DP的状态设计是最难的首先看阶段&#xff0c;就是第i个人然后影响决策的因素就是&#xff0c;女生不能…

【docker mysql】docker 快速安装mysql和redis

docker_hub 官网&#xff1a;点击docker_hub仓库地址 docker run --name mysql-bear -p 3307:3306 -e MYSQL_ROOT_PASSWORDmysql-bear -d mysql:latestdocker run --name redis-bear -p 6479:6379 -d redis再次使用docker ps 命令查看即可。 我这里把端口映射到主机上了&…

【Axure教程】橡皮擦的擦除效果——刮奖原型

橡皮擦的擦除效果是系统常见的效果&#xff0c;在可以画图编辑的系统中或者是在抽奖刮奖的系统中非常常见。所以今天和大家分享在Axure中如何制作橡皮刷的效果&#xff0c;我们会议刮奖原型为案例&#xff0c;教大家制作出一个刮奖效果的高保真原型模板。一、效果展示1、鼠标移…

做测试一定要知道的——软件测试流程和测试规范标准文档

目录 1、目的 2、工作范围 3、工作职责 4、测试的流程 5、测试准备阶段 6、测试方法制定阶段 7、测试执行阶段 8、bug管理 9、标准文档 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 1、目的 通…

关于Thread.start()后的困惑、imap

在for循环中&#xff0c;接着开thread&#xff0c;开完就start&#xff0c;当时有个困惑&#xff0c;就是比如开的一个thread的这个start执行完&#xff0c;但是这个for循环还没执行完&#xff0c;那程序会跑到for循环的后面逻辑吗&#xff1f;比如下面13行for循环开始开第一个…

浅谈子网掩码、IP地址、网络地址之间关系

文章目录一、什么是子网掩码二、给定IP地址&#xff0c;如何求网络地址网络标识&#xff08;net-id&#xff09;和主机标识&#xff08;host-id&#xff09;计算步骤三、CIDR地址表示方法(Classless Inter Domain Routing)四、IP地址与MAC地址一、什么是子网掩码 在TCP/IP协议…

阿里云云原生每月动态 | 聚焦实战,面向开发者的系列课程全新上线

作者&#xff1a;云原生内容小组 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 本栏目每月更新。 趋势热点 《云原生实战指南》白皮书发布 …

如何使用金山轻维表发送生日祝福、入职纪念日祝福

作为企业HR或行政&#xff0c;如果能在员工生日当天发送一份生日祝福生日礼物&#xff0c;是不是可以给员工强烈的归属感和惊喜&#xff0c;但核查员工生日需要每天对着花名册查询&#xff0c;或单独设置提醒&#xff0c;对HR行政来说又比较繁琐复杂&#xff0c;还经常容易忘&a…

matlab - 特殊矩阵、矩阵求值、稀疏矩阵

学习视频1.特殊矩阵1.1 通用特殊矩阵format % 零矩阵(全0) 幺矩阵(全1) 单位矩阵 % zeros ones eye rand(生成0~1的随机元素) randn(生成均值为1&#xff0c;方差为0的符合正太分布的随机阵)zeros(3) % 3x3的全0方阵 zeros(3, 4) % 3x4的全0矩阵 exA ones(3, 5) % 3x5的…

mapbox-gl实现 2.5D 图层高度编辑器

文章目录前言表达式逻辑mapbox表达式转数学表达式数学表达式转mapbox表达式实现效果前言 mapbox-gl 支持表达式编辑 2.5D 建筑物高度&#xff0c;但是 style 文件原生的表达式很不直观&#xff0c;本文实现一个简单的 2.5D高度图层编辑器&#xff0c;核心是理解mapbox表达式规…