day05-面向对象内存原理和数组

news2024/11/13 11:49:56

day05 面向对象内存原理和数组

我们在之前已经学习过创建对象了,那么在底层中他是如何运行的。

1.对象内存图

1.1 Java 内存分配

Java 程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

在这里插入图片描述

在这里插入图片描述

Cat cat = new Cat();

突出了解对于堆栈的学习。

1.2 堆和栈

:所有局部变量都会在栈内存中创建
局部变量:定义在方法中的变量或者方法声明上的变量

方法执行都会加载到栈中进行

局部变量特点:随着方法的调用而存在,随着方法的调用完毕而消失

代码:Student s = new Student();
:所有对象及其对应的实例变量和数组都将存储在此处
简单理解为:new出来的东西,都存储在堆内存
每一个new出来的东西都有一个地址值,使用完毕,会在垃圾回收器空闲时被回收
实例变量(成员变量)有初始化值:
基本数据类型:整数:0,浮点数:0.0,布尔:false,字符:空字符
引用数据类型:null

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

区别成员变量局部变量
类中位置不同类中方法外方法内或者方法声明上
内存中位置不同堆内存栈内存
生命周期不同随着对象的存在而存在,随着对象的消失而消失随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同有默认的初始化值没有默认的初始化值,必须先定义,赋值,才能使用
单个对象 指向一个地址

多个对象 指向对应数量的多个地址

多个引用指向相同  地址可以为同一个

1.3 堆-栈内存总结

1.new 对象会创建堆内存
2.声明变量 只创建栈内存
3.多个变量可以指向一个对象
4.局部变量存在栈内存,用完就消失,作用范围仅限方法或者局部{}范围
5.成员变量会存在堆内存,随着对象消失才消失,作用范围类范围

2.private

是一个权限修饰符
可以修饰成员(成员变量和成员方法)
作用是保护成员不被别的类使用,被 private 修饰的成员在本类中可以通过 实例对象.属性名进行访问。

针对 private 修饰的成员变量,如果需要被其他类使用,提供两个相应的操作:
提供“get变量名()”方法,用于获取成员变量的值,方法用 public 修饰
提供“set变量名(参数)”方法,用于设置成员变量的值,方法用 public 修饰

eg:

public class Student {
    private String name;
    public String getName() {
        return name;   
        }
    public void setName(String name) {
        this.name = name;
    }
    //被 private 修饰的成员在本类中可以通过实例对象.属性名进行访问
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.name);
    }
}
public class People {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.name);//报错!!
    }
}

3.this

this:方法被哪个对象调用,this就代表哪个对象。

① 什么时候使用this呢?

解决局部变量隐藏成员变量

局部变量和成员变量名字一致,局部变量赋值给成员变量。

② this限定的变量用于指代成员变量

方法的形参如果与成员变量同名,
不带this修饰的变量指的是形参,而不是成员变量
方法的形参没有与成员变量同名,
不带this修饰的变量指的是成员变量

public class Student { 
	private String name;  
	public String getName() {
        return name;   
        }
    public void setName(String name) {
        this.name = name;
    }
}
 public void setName(String username) {
        name = username;//这里可以不用this
    }

4.封装

1.封装概述

是面向对象三大特征之一(封装,继承,多态
是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的

eg:相当于把水放在一个水杯中,只能通过水杯出水口喝水。 外界是无法拿到水,只能通过一个公共的出口取水。

2.封装原则

将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
成员变量private,提供对应的**getXxx()/setXxx()**方法

3.封装好处

通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性

规范代码:

public class Student {
	private String name;
	public String getName() {
        return name;
        }
    public void setName(String name) {
        this.name = name;
    }

    private int age;
    public int getAge() {
        return age;    }
    public void setAge(int age) {
        this.age = age;
    }
}

快捷方式:alt+insert 选择getterAndSetter

5.构造方法

5.1 构造方法概述

构造方法是一种特殊的方法

作用:创建对象

格式:

public class 类名{        

修饰符 类名(参数) {       

 }}

功能:主要是完成对象数据的初始化

5.2 构造方法的注意事项

① 构造方法的创建

如果没有定义构造方法,系统将给出一个默认无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法

② 构造方法的重载

如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法

③ 推荐的使用方式

永远提供无参数构造方法

5.3 JavaBean

就是一个Java中的类,其对象可以用于在程序中封装数据
举例:学生类,手机类

标准 JavaBean 须满足如下要求:
1.成员变量使用 private 修饰
2.提供每一个成员变量对应的 setXxx() / getXxx()
3.提供一个无参构造方法

5.4 练习

手机 JavaBean

需求:编写手机 JavaBean,并在测试类中使用
提示:手机有成员变量brand(品牌)和price(价格)

6.数组

数组概述

为了存储一个学员的考试成绩,我们可以采用一个变量进行存储,如果我有很多个学员的考试成绩,我们也可以用多个变量进行存储。但是,如果学员人数太多,这样定义变量就太麻烦了,这就对我们存储数据提出了新的诉求:一次性声明大量的用于存储数据的变量,要存储的数据通常都是同类型数据,例如:考试成绩。满足这种诉求的东西是什么呢?就是我们接下来要讲解的数组。来我们说一下什么是数组。

int a = 100int b = 100int c = 100int d = 100int e = 100int f = 100int g = 100… …

在这里插入图片描述

一次性声明大量的用于存储数据的变量

要存储的数据通常都是同类型数据,

例如:考试成绩int[] scores = {100,100,100,100,100,100,100…};

什么是数组

数组(array):是一种用于存储多个相同数据类型的存储模型(可以理解为容器)

1.数组定义格式

格式1数据类型[] 变量名;
范例: int[] arr;
定义了一个int类型的数组,数组名是arr

格式2数据类型 变量名**[];
范例: int arr
[]**;
定义了一个int类型的变量,变量名是arr数组

推荐使用:格式1

2.数组初始化概述

静态初始化
动态初始化

2.1.数组初始化之静态初始化

静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度

格式:数据类型[] 变量名 = new 数据类型[]{数据1,数据2,数据3,…};

范例:int[] arr = new int[]{1,2,3};

简化格式:数据类型[] 变量名 = {数据1,数据2,数据3,…};

范例:int[] arr = {1,2,3};

2.2 数组初始化之动态初始化

动态初始化:初始化时只指定数组长度,由系统为数组分配初始值

格式:数据类型[] 变量名 = new 数据类型[数组长度];

范例:int[] arr = new int[3];

使用场景:
静态初始化:开始就存入元素值,适合一开始就能确定元素值的业务场景
动态初始化:指定数组长度,后期赋值,适合开始知道数据的数量,但是不确定具体元素值的业务场景
注意:两种初始化的方式是独立的,不可以混用

int[] arr = new int[3]{30,40,50}; //错!!!!

2.3 数组元素来自键盘录入

需求:定义一个可以存储5个元素的int数组,数据来自于键盘录入,最后遍历数组,把元素输出在控制台

分析:
① 数组长度可知,元素未知,采用动态初始化
② 键盘录入,使用Scanner实现

eg:

 public static void main(String[] args) {
        int[]arr = new int[5];
        Scanner sc = new Scanner(System.in);

        for (int j = 0; j < 5; j++) {
            System.out.println("请输入第" + (j+1) + "个数");
            arr[j] = sc.nextInt();
        }
        printArray(arr);
    }
    public static void printArray(int[] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if(i==arr.length-1) {
                System.out.print(arr[i]);
            }else {
                System.out.print(arr[i] + ", ");
            }
        }
        System.out.println("]");
    }

3.数组元素访问

3.1 数组变量访问方式
格式:数组名
3.2 数组内部保存的数据的访问方式
格式:数组名[索引]
3.3 索引是数组中数据的编号方式

作用:索引用于访问数组中的数据使用,数组名[索引]等同于变量名,是一种特殊的变量名
特征①:索引从0开始
特征②:索引是连续的
特征③:索引逐一增加,每次加1

4.数组常见操作

4.1遍历

什么是数组遍历
获取数组中的每一个元素,我们可以把获取到的元素输出在控制台

获取数组长度(元素个数)

格式:数组名.length

范例:arr.length

数组遍历通用格式:

int[] arr = {...};
for (int i = 0; i < arr.length; i++) { 
arr[i]; //对元素arr[i]进行操作
}

注意:数组遍历指的是把数组中的元素取出来,取出来之后可以(打印,求和,判断…)

4.2 获取最大值

在这里插入图片描述
获取数组中最大值

  public static void main(String[] args) {
        //定义数组
        int[] arr = {12, 45, 98, 73, 60};

        //定义变量max存储最大值,取第一个数据为变量的初始值
        int max = arr[0];

        //与数组中剩余数据逐个比对,每次比对将最大值保存到变量max中
        for (int i=1; i<arr.length; i++) {
            if(arr[i] > max) {
                max = arr[i];
            }
        }

        //循环结束后输出变量max的值
        System.out.println("max:" + max);
    }

4.3 元素打乱

把数组中的元素随机交换位置,每次运行都可能产生不一样的结果
比如:arr = {12, 45, 98, 73, 60};
遍历:
正常情况下:12,45,98,73,60
元素打乱后:45,73,12,60,98
涉及到的操作
获取数组中元素的随机索引

Random r = new Random();
int index = r.nextInt(arr.length);

数组中元素交换

int a = 10;
int b = 20;
int temp = a;
a = b;
b = temp;
System.out.println(a);
System.out.println(b);

元素打乱案例

public static void main(String[] args) {
        //定义数组
        int[] arr = {12, 45, 98, 73, 60};

//        Random r = new Random();
//        int index = r.nextInt(arr.length);
//
//        //第一次交换
//        int temp = arr[0];
//        arr[0] = arr[index];
//        arr[index] = temp;
//
//        //第二次交换
//        index = r.nextInt(arr.length);
//        temp = arr[1];
//        arr[1] = arr[index];
//        arr[index] = temp;

        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            int index = r.nextInt(arr.length);

            int temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }
        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

5.思考问题数组常见问题

请问下列代码有问题吗?

int[] arr = new int[3];//输出元素
System.out.println(arr[3]);

如果有,是什么问题?

如何解决?

有问题访问了不存在的索引位置元素修改不存在的索引为正确的索引。范围(0~数组长度-1)

int[] arr = new int[3];
System.out.println(arr[2]);//把 null赋值给数组
arr = null;// 输出元素
System.out.println(arr[0]);
数组使用中的两个小问题
    1:索引越界:访问了数组中不存在的索引对应的元素,造成索引越界问题
        ArrayIndexOutOfBoundsException

    2:空指针异常:对象不再指向堆内存,还想继续访问数据,访问失败
        NullPointerException

    null:空值,引用数据类型的默认值,表示不指向任何有效对象

6.二维数组(自学作业)

需求:我们要存储多个班级的学生的考试成绩,该怎么办呢?
如果要存储一个班级中多个学生的考试成绩,我们就可以采用数组来存储。
多个班级的考试成绩,我们针对每个班级都采用数组存储:
第一个班级:数组1
第二个班级:数组2
第三个班级:数组3

但是多个班级也可以采用数组存储啊?所以,Java就提供了二维数组供我们使用

6.1二维数组概述

二维数组:元素为一维数组的数组

定义格式:

数据类型[][] 变量名;	int[][] arr;//重点	
数据类型 变量名[][];	int arr[][];
数据类型[] 变量名[];	int[] arr[];

6.2二维数组初始化

6.21静态初始化

1.格式:

数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…},…};

2.范例:

int[][] arr = new int[][]{{1,2,3},{4,5,6},{7,8,9}};

3.解读

定义了一个二维数组
二维数组中有三个元素(一维数组)
每一个一维数组有三个元素(int类型数据)

4.注意:一维数组中元素的个数可以是不同的

举例: int[][] arr = new int[][]{{1,2,3},{4,5},{6,7,8,9}};

5.简化格式:

数据类型[][] 变量名 = {{元素…},{元素…},{元素…},…};

6.范例:

int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
6.22 动态初始化

1.格式:

数据类型[][] 变量名 = new 数据类型[m][n];

2.范例:

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

3.解读

定义了一个二维数组
二维数组中有2个元素(一维数组)
每一个一维数组有3个元素(int类型数据)
6.23 二维数组元素访问
获取二维数组:数组名
获取每一个一维数组:数组名[索引]  从0开始
获取每一个二维数组元素:数组名[索引][索引]  从0开始
6.24 二维数组常见操作

遍历&元素打乱

1.二维数组遍历

需求:已知一个二维数组 arr = {{1,2,3},{4,5,6},{7,8,9}}; 请把元素在控制台输出
二维数组中循环嵌套的使用:
① 循环嵌套:循环语句中嵌套循环语句
② 外层循环得到一维数组
③ 内存循环得到每一个二维数组元素
 public static void main(String[] args) {
        int[][]arr = {{1,2,3},{4,5,6},{7,8,9}};
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.println(arr[i][j]);
            }
        }
    }

2.二维数组元素打乱

需求:已知二维数组 arr = {{1,2,3},{4,5,6},{7,8,9}};
用程序实现把数组中的元素打乱,并在控制台输出打乱后的数组元素
public static void main(String[] args) {
        int[][]arr = {{1,2,3},{4,5,6},{7,8,9}};
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                //arr[i][j]
                int a = r.nextInt(arr.length);
                int b = r.nextInt(arr.length);
                //元素交换
                int temp = arr[i][j];
                arr[i][j] = arr[a][b];
                arr[a][b]= temp;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[i][j]+" ");
            }
        }
    }
    int[][]arr = {{1,2,3},{4,5,6},{7,8,9}};
    Random r = new Random();
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            //arr[i][j]
            int a = r.nextInt(arr.length);
            int b = r.nextInt(arr.length);
            //元素交换
            int temp = arr[i][j];
            arr[i][j] = arr[a][b];
            arr[a][b]= temp;
        }
    }
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            System.out.print(arr[i][j]+" ");
        }
    }
}

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

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

相关文章

leetcode——反转链表

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;创建三个指针n1,n2,n3&#xff0c;遍历原链表&#xff0c;通过三者之间的关系将链表反转。下面给出图示&#xff1a; 下面给出题解代码&#xff1a; typedef struct ListNode ListNode; struct List…

C++入门指南(上)

目录 ​编辑 一、祖师爷画像 二、什么是C 三、C发展史 四、C在工作领域的应用 1. 操作系统以及大型系统软件开发 2. 服务器端开发 3. 游戏开发 4. 嵌入式和物联网领域 5. 数字图像处理 6. 人工智能 7. 分布式应用 五、如何快速上手C 一、祖师爷画像 本贾尼斯特劳斯…

vmware虚拟机内删除文件后宿主机空间不释放

问题描述 linux下&#xff0c;vmware内虚拟机删除文件&#xff0c;宿主机空间不释放&#xff0c;D盘快满了 解决方法 通过vmware-toolbox进行空间回收 安装 在虚拟机内操作 yum install -y open-vm-tools 清理 在虚拟机内操作 #查看磁盘的挂载点 sudo /usr/bin/vmware…

设计模式-结构型-桥接模式-Bridge

桥接模式可以减少类的创建 矩阵类 public class Matrix {private String fileName;public Matrix(String fileName) {this.fileName fileName;}public String getFileName() {return fileName;} } 图片抽象类 public abstract class Image {protected ImageImp imp;public …

C#二维数组(矩阵)求伴随矩阵和逆矩阵

程序框架及winform窗体 窗体控件: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Matrix {internal class Algorithm_Gallery{// <summary>/// 计算 A[p,q] 位于 [,]temp 的块辅因子…

Oracle数据库之 常用数据库对象(二)

目录 1.视图 1.1.什么是视图&#xff1f; 1.2.创建视图的语法 1.3.简单视图和复杂视图 1.4.创建复杂视图 1.4.1.创建复杂视图的步骤 1.4.2.示例 1.4.3.注意事项 1.5.视图中使用DML的规定 1.5.1.屏蔽DML操作 1.6.删除视图 2.序列 2.1.语法&#xff1a; 2.2.查询序…

【AI源码】音频和图片生成你的数字人口播

带表情、带头部运动。适合做一些名人短视频鸡汤口播 类似此前微软和阿里emo那个方案 1、介绍: 能够通过单张静态肖像和输入音频生成具有自然流动运动的谈话视频,它采用了一种普遍的运动表示方法,能够捕捉广泛的面部动态,包括细微的表情和头部运动。 2、框架概述 (1)该…

【18-Ⅰ】Head First Java 学习笔记

HeadFirst Java 本人有C语言基础&#xff0c;通过阅读Java廖雪峰网站&#xff0c;简单速成了java&#xff0c;但对其中一些入门概念有所疏漏&#xff0c;阅读本书以弥补。 第一章 Java入门 第二章 面向对象 第三章 变量 第四章 方法操作实例变量 第五章 程序实战 第六章 Java…

信息检索(37):Query-as-context Pre-training for Dense Passage Retrieval

Query-as-context Pre-training for Dense Passage Retrieval 标题摘要1 引言2 初步&#xff1a;上下文监督预训练2.1 coCondenser2.2 CoT-MAE 3 查询即上下文预训练3.1 预训练3.2 微调 4 实验4.1 预训练4.2 微调4.3 基线4.4 主要结果4.5 域外评估 5 分析5.1 生成的查询数量的影…

【QuikGraph】C#调用第三方库实现迪杰斯特拉(Dijkstra)算法功能

QuikGraph库介绍 项目地址&#xff1a;https://github.com/KeRNeLith/QuikGraph QuikGraph为.NET提供了通用的有向/无向图数据结构和算法。 QuikGraph提供了深度优先搜索、广度优先搜索、A*搜索、最短路径、k最短路径&#xff0c;最大流量、最小生成树等算法。 QuikGraph最初…

【一支射频电缆的诞生】GORE 戈尔

工具连接&#xff1a; https://microwave-cablebuilder.gore.com/ 控制参数&#xff1a; 连接器&#xff1a; 欣赏

基于yolov8+gradio目标检测演示系统设计

YOLOv8与Gradio&#xff1a;开启目标检测的可视化新篇章 随着人工智能技术的飞速发展&#xff0c;目标检测作为计算机视觉领域的重要分支&#xff0c;已经广泛应用于安防监控、自动驾驶、医疗影像等多个领域。而YOLO&#xff08;You Only Look Once&#xff09;系列算法作为目…

力扣每日一题124:二叉树中的最大路径和

题目 困难 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root…

Python 将Excel转换为多种图片格式(PNG, JPG, BMP, SVG)

目录 安装Python Excel库 使用Python将Excel工作表转换为PNG&#xff0c;JPG或BMP图片 使用Python将Excel特定单元格区域转换为PNG&#xff0c;JPG或BMP图片 使用Python将Excel工作表转换为SVG图片 有时&#xff0c;你可能希望以图片形式分享Excel数据&#xff0c;以防止他…

视频封面一键提取:从指定时长中轻松获取您想要的帧图片

在数字媒体时代&#xff0c;视频已成为人们获取信息、娱乐和沟通的主要形式之一。而一个好的视频封面&#xff0c;往往能够吸引观众的眼球&#xff0c;增加视频的点击率和观看量。然而&#xff0c;对于很多视频创作者和编辑者来说&#xff0c;如何从视频中快速、准确地提取出合…

时序分解 | Matlab实现LMD局域均值分解

时序分解 | Matlab实现LMD局域均值分解 目录 时序分解 | Matlab实现LMD局域均值分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 时序分解 | Matlab实现LMD局域均值分解 Matlab语言 1.算法新颖小众&#xff0c;用的人很少&#xff0c;包含分解图 2.直接替换数据即可用…

进入泛型的世界

泛型的理解和好处 泛型的好处 编译时&#xff0c;检查添加元素的类型&#xff0c;提高了安全性减少了类型转换的次数&#xff0c;提高效率 不使用泛型 Dog-加入->Object-取出->Dog&#xff08;向下转型&#xff09; Dog放入到ArrayList 会先转成Object&#xff0c;在转…

数据分享—中国土壤有机质数据

土壤有机质数据是进行区域土地资源评价&#xff0c;开展自然地理研究常使用的数据&#xff0c;本期推文主要分享全国土壤有机质数据集。梧桐君会不定期分享地理信息数据&#xff0c;欢迎大家长期订阅。 数据来源 “万物土中生”&#xff0c;小编今天要分享的中国土壤有机质数…

通过mvn archetype 创建一个spring boot start 工程

mvn archetype https://maven.apache.org/archetype/index.html 遇到的问题 对于想自定义一个spring-boot-start的同学,比如 Springboot自定义Starter启动器 整个过程很繁琐。 定义属性开关增加 spring boot test start插件定义自动装载 spring.factories or org.springfra…