当前位置: 首页 > ai >正文

硅基计划2.0 学习总结 肆 初稿

图 (907)

文章目录

    • 1. 二维数组补充
      • 1. 是特殊一维数组
      • 2. 求数组长度
      • 3. 遍历
      • 4. toString和ddeepToString
      • 5. 默认值
    • 2. 类和对象
      • 1. 定义类(class)
      • 2. 实例化类
      • 3. 使用对象
    • 3. this关键字
    • 4. 交换变量值
    • 5. 就地/默认初始化
      • 1. 就地初始化
      • 2. 构造方法初始化
      • 3. 调用构造方法
      • 4. 嵌套调用
      • 5. 对象的打印
    • 6. 其他注意要点


1. 二维数组补充

  • 在创建数组的时候,你new一个对象,要明确行和列,每一行可以用“{}”区分
int [] [] array = new int [][]{{1,2,3},{4,5,6}};

当然写的时候你也可以明确行和列

int [] [] array = new int [2][3];

1. 是特殊一维数组

image-20250525212925598
我们从图中就可以看到,二位数组中的每一个元素本质上都为一个个一维数组
即存的地址,这个地址指向其所指向的一维数组对象

2. 求数组长度

  1. array.length求的是二维数组的行数,通过我们刚刚画图
    我们可以知道,二维数组你可以把它看为特殊的一维数组
    求长度不就是求有多少个一维数组
  2. array[i].length求的是第i行有多少个元素,即列数
    即二维数组中每一个一维数组所指向的对象的数组的长度(抽象成二维数组列数)

3. 遍历

public static void main(String[] args) {int [] [] array = new int [] []{{1,2,3},{4,5,6}};for(int [] tmp:array){for(int x:tmp){System.out.print(x+" ");}System.out.println();}}
  • 为什么有两层循环遍历呢,因为二位数组本质是一个个一维数组
    因此我们先要把二维数组(看成一维数组前提下)每一个元素取出来
    因此我们就要用int [] tmp数组类型来接收
    接收后我们就要接着循环打印每一个一维数组
    就正常给一个变量接收每一个一位数组中的每一个元素

4. toString和ddeepToString

如果你使用toString去转换数组,打印的结果只会是二维数组中每一个一维数组地址
而使用ddeepToString才会打印整个数组内容
image-20250525215301829

5. 默认值

int [] [] array = new int [2] [];//行必写,列可省
System.out.println(Arrays.toString(array1));

打印的结果是两个null,即没有指向任何对象,因为数组是引用数据类型
若你单独给每一行初始化

array1[0] = new int [3];
array1[1] = new int [3];
System.out.println(Arrays.deepToString(array1));

打印的结果就是全是0,说明给每一行创建对象后
二维数组中每一个元素都有其指向的一维数组的对象,默认初始化就是0了


2. 类和对象

1. 定义类(class)

  1. 格式:class (类名) {......} ,“{}”中写类的成员变量(属性)和成员方法

这里有几个注意事项:

  1. 区分下成员变量和局部变量:成员变量在类中但在方法之外,局部变量在方法内
  2. 这边建议一个类放在一个Java文件中(一个类对应一个字节码文件class)
  3. 类的命名采用大驼峰(每个单词首字母大写)
  4. 成员变量和成员方法都分为静态(static修饰)和非静态
  5. 如果使用Idea编译器,在当前类中定义了其他类,会有警告,此时我们可以剪切代码,剪切后直接点击SRC文件然后ctrl+粘贴,自动生成了一个以你剪切的这个类名的Java文件
  6. 如果你想修改类名,不能直接在代码中修改,通过Idea编译器选择对应Java文件重命名,重命名之后,其他类中有你当前这个类的类名也会跟着改变

以下是示例代码,定义了一个学生的类

public class Student {public int age;public int high;public String name;public void print(){System.out.println(age+" "+high+" "+name);}}

2. 实例化类

在main方法中,通过new关键字来创建对象,而且可以new多个对象

Student stu1 = new Student();
Student stu2 = new Student();
Student stu3 = new Student();

其中Student相当于类型(类比iint a = 10;),stu1相当于对象名称

3. 使用对象

  1. 究竟new了什么
  • 我们画个图来讲解
    image-20250526100757180
  1. 访问和修改属性

对于类中成员变量,我们可以通过对象名.属性访问活修改,进而可以给多个对象中的成员变量赋值
stu1.age = 18stu2.age = 19stu3.age = 20;
并且不同对象在堆中的位置都不一样,因此每个对象中同一个成员变量的值可能不同

  1. 访问成员方法
  • 格式:对象名.方法名();

补充:可以双击shift查看这个类中有哪些成员变量
image-20250526121253870

3. this关键字

  1. 写一个方法给成员变量赋值
public void setStudent(int a,int h,String n){age = a;high = h;name = n;
}
//赋值成功后我们在main方法中再调用setStudent方法,再传值,再看结果  
Student stu1 = new Student();
stu1.setStudent(19,180,"zlh");
stu1.print();

image-20250526102213395

  • 但是你这么想,我有那么多对象,而你只有一个类,怎么对这些对象做区分呢,我每一个对象都赋予不同的值,编译器是如何区分不同对象的呢?
  1. this关键字应用场景
  • 当你把形参名改成和成员变量名一致的时候
public void setStudent(int age,int high,String name){age = age;high = high;name = name;
}
  • 此时你再传值的时候,你会发现调用print方法打印结果都变成0了,为什么?而且在类中编译器也会爆出警告,形参自己给自己赋值了
    image-20250526102852352
  • 如果此时你添加this关键字指向当前对象中的age,high,name的值,就正常了
public void setStudent(int age,int high,String name){
        this.age = age;this.high = high;this.name = name;

}

![image-20250526102213395](https://i-blog.csdnimg.cn/img_convert/12cf4f1335bfa68be49b4561602454c1.png)  
因此我们得以知道,this关键字作用就是**每次对象调用的时候通过this来指向当前调用的对象**  
进而我们知道了当多个对象调用一个方法的时候(比如setStudent),this就看谁调用了这个方法,那我就指向谁,就给哪个对象赋值  
因此其实在setStudent中有一个隐藏的参数`setStudent(Student this,......)  
  1. 调用当前对象中成员方法
public void setStudent(Student this,int age,int high,String name){this.age = age;this.high = high;this.name = name;this.print();}public void print() {System.out.println(age + " " + high + " " + name);
}
//在main方法中无需再调用对象stu1的print成员方法了
Student stu1 = new Student();
stu1.setStudent(19,180,"zlh");

image-20250526102213395

4. 交换变量值

核心思想就是利用this关键字在调用类的时候指向调用类的对象(通常是不同的)来达到交换目的

public static void swap (MyValue myValue1,MyValue myValue2){
int tmp = myValue1.val;
myValue1.val = myValue2.val;
myValue2.val = tmp;
}//此时的myValue1中存的是其对象地址,myValue2也是存的其对象地址,前面都是类的类型MyValue myValue1 = new MyValue();
myValue1.val = 10;
MyValue myValue2 = new MyValue();
myValue2.val = 20;
System.out.println();
System.out.println("调换前:"+myValue1.val+" "+myValue2.val);
System.out.println("---------------");
swap(myValue1,myValue2);//传两个对象,即引用传值
System.out.println("调换后:"+myValue1.val+" "+myValue2.val);//MyValue方法中
public class MyValue {public int val;
}

image-20250526110533287

5. 就地/默认初始化

成员变量中不给初始值,其成员变量也会存在默认值,引用类型为null,布尔类型为flase

1. 就地初始化

指的是在创建成员变量的时候直接赋值public int age = 18;,即默认初始值,后续可以再改变值
只不过不能在成员变量中改变了public int age = 18; age = 20;是不可以的

2. 构造方法初始化

它是特殊的方法,无返回值且与类名相同,分为带参数和不带参数,其目的就为了初始化成员变量,本质上是方法的重载

  1. 这个是无参构造方法
public Student(){this.age = 18;this.high = 180;this.name = "zlh";
}
  1. 这个是有参构造方法
public Student (int age,int high,String name ){this.age = age;this.high = high;this.name = name;
}

3. 调用构造方法

何时调用:在实例化对象的时候调用

Student stu1 = new Student(19,180,"zlh");

你在new对象的时候给了什么样的参数(或者不给参数),就会调用对应参数列表的对应构造方法

本质上一个对象的产生:为对象分配内存–>调用合适的构造方法

两种构造方法都可以并存,但是有几点要注意:

  1. 如果类中不存在构造方法,Java会给默认的无参构造方法
  2. 若已经有一个构造方法了(假设是有参),此时你类创建对象的时候你再调用无参构造方法会报错,因为编译器认为你已经有一个构造方法了,无需再提供无参构造方法,因此只有在无构造方法前提下不写无参构造方法编译器才会给你在new过程中默认提供无参构造方法
  3. 构造方法在对象创建中只会调用一次,构造方法可以重载(多个)

4. 嵌套调用

可以使用this(),括号中填写你想调用的那个构造方法的参数列表
比如你可以写this(18,180,"zlh")来调用public Student (int age,int high,String name )这个构造方法

注意:

  1. 此时你已经调用了其他构造方法,在其他构造方法中执行完流程后,会回到当前构造方法,执行下一行代码
  2. 调用其他构造方法的时候,必须把this()写在当前构造方法的第一张,否则报错
  3. (假设当前是A构造方法)不能调用了B构造方法,再在B中调用A构造方法(调回来),不能形成环

5. 对象的打印

不觉得每次类中都要写print成员方法打印类的成员变量很麻烦吗,Java中提供便利
image-20250526113933757
生成了如下代码:

@Overridepublic String toString() {return "Student{" +"age=" + age +", high=" + high +", name='" + name + '\'' +'}';
}
//在main方法中可以直接打印
System.out.println(stu1);

打印结果是:Student{age=19, high=180, name=‘zlh’},还可以自定义打印格式

我们看到借助println打印,我们点开println内部看看

public void println(Object x) {String s = String.valueOf(x);if (getClass() == PrintStream.class) {// need to apply String.valueOf again since first invocation// might return nullwriteln(String.valueOf(s));} else {synchronized (this) {print(s);newLine();}}}

我们看到是调用了一个valueOf方法,我们再点开看

public static String valueOf(Object obj) {return (obj == null) ? "null" : obj.toString();}

我们可以看到在三元判别式中又调用了一个toString方法,我们再点开看

public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}

这个打印格式是不是很熟悉Student{age=19, high=180, name='zlh'}
getClass对应类名,后面对应的是成员变量名,我目前只是水平只能解释到这里
而且如果你没有在类中写toString,则会打印对象地址,否则就执行你的toString方法

6. 其他注意要点

  1. Student stu1 = null;表示p不指向任何对象,而不是空对象,空对象也可能是个对象
  2. 一个对象可以被多个引用指向,而一个引用只能指向一个对象

文章内容难免有错误,欢迎各位大佬指出

本文章演示所用代码
Git码云仓库链接

END
http://www.xdnf.cn/news/9071.html

相关文章:

  • 深度学习---可视化
  • Linux wget 常用命令详解
  • AI时代新词-AI伦理(AI Ethics)
  • 【Linux】磁盘管理,虚拟机CentOS扩展根分区
  • 像造汽车一样造房子:装配式建筑4.0如何重塑未来人居
  • 启程:MCP开发环境配置和旅游攻略案例体验
  • 基于NSGA2算法的无人机航迹规划算法
  • BaseProviderMultiAdapter多布局总结
  • vertica优化
  • 网口XDP-报文回环转发
  • 知识图谱系列(3):构建方法与流程
  • vue3获取两个日期之间的所有时间
  • 解决leetcode第3509题.最大化交错和为K的子序列乘积
  • OceanBase数据库全面解析(高级特性篇)
  • Real2Render2Real:无需动力学仿真或机器人硬件即可扩展机器人数据
  • AI智能混剪核心技术解析(一):字幕与标题生成的三大支柱-字幕与标题生成-优雅草卓伊凡
  • 海思3519V200ARM Linux 下移植 Qt5.8.0
  • 开疆智能Profinet转Profibus网关连接丹佛斯FC300变频器配置案例
  • Windows11+WSL2+Ubuntu22 安装
  • 汽车恒温器行业2025数据分析报告
  • 【Pandas】pandas DataFrame drop_duplicates
  • 【springMVC】springMVC学习系列一:springMVC的组件
  • 调度算法中的轮盘赌与锦标赛选择算子:优势对比与选择策略
  • 创建一个简易的风扇动画界面:基于 WPF 和 XAML 的实现教程
  • 第Y1周打卡——调用官方权重进行检测
  • 每日算法 -【Swift 算法】字符串转整数算法题详解:myAtoi 实现与正则表达式对比
  • 直线参数方程何时必须化为标准形式 |新高考已删
  • golang channel 的特点、原理及使用场景
  • 人工智能 - Magentic-UI与Browser Use 技术选型
  • C++基础算法————递推