数组
数组定义,以及注意事项:
数组的定义:数据类型[] 数组名 = new 数据类型[数组长度]
Java中的数组必须先初始化才能够使用
初始化:就是为数组中的数组元素分配内存空间,并每个数组元素赋值
静态初始化:在定义数组的时候就已经确定了数组的存储元素
动态初始化:在定义数组的时候明确了数组的长度,但是不确定数组存储元素
数组定义格式:
- 格式一: 数据类型[] 变量名
- int[] arr
- 定义了一个int类型的数组,变量名是arr
- 格式二:数据类型 变量名[]
- int arr[]
- 定义了一个int类型的变量,变量名是arr数组
注意事项:
1、数组属于引用数据类型
2、数组必须要有长度
3、数组的长度,在运行时不能改变
4、存储的元素数据类型需与数组的数据类型保持一致
数组元素的访问:
数组变量访问方式:
格式:数组名
数组内部保存的数据的访问方式:
格式:数组名[索引]
索引是从0开始的,索引是连续的,索引逐一增加,每次加1
import java.util.Scanner;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// 静态初始化
int[] Arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = 0; i < Arr.length; i++) {
System.out.println(Arr[i]);
}
// 动态初始化
int[] Array = new int[10];
for (int i = 0; i < Array.length; i++) {
Array[i] = input.nextInt();
}
for (int i = 0; i < Array.length; i++) {
System.out.println(Array[i]);
}
/* 数组间赋值,实际上把地址给到另外一个数组,共用地址空间*/
int[] A1 = {1, 2, 3, 4};
//查看当前数组A1的首地址
System.out.println(A1);
int[] A2;
A2 = A1;
//查看数组A2的首地址,比较两个输出结果,输出相同的地址
System.out.println(A2);
}
数组在初始化时,会为存储空间添加默认值
整数:默认值是0
浮点数:默认值0.0
布尔值:默认是false
字符:默认值是空字符
引用数据类型:默认值是null
数组操作中的常见问题:
1、数组访问越界:访问了数组中不存在的索引对应的元素,造成索引越界问题
2、空指针异常:访问的数组已经不再指向堆内存的数据,造成空指针异常
public class Main {
public static void main(String[] args) {
int[] arr = new int[5];
// System.out.println(arr[5]);//程序报错 数组越界 java.lang.ArrayIndexOutOfBoundsException
int[] arr2 = new int[5];
arr2=null;
System.out.println(arr2[0]);//访问数组已经不再指向堆内存数据java.lang.NullPointerException
}
}
遍历数组
public class Main {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5};
//数组遍历两种方式
//明确了数组的长度的
for (int i = 0; i < 5; i++) {
System.out.println(arr[i]);
}
//不明确数组长度,arr.length获取数组的长度
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
类与对象、封装、构造方法
类是对象的数据类型
类是一种相关属性和行为对象的集合
属性:事物的状态信息
行为:事物所能做什么
对象:类的一个实例
对象的行为:对象能够执行的操作
类和对象的关系:
类是对现实生活中一类具有共同属性和行为的事物的抽象
对象是能够看得到摸得着的真实存在的实体
区别:
类是抽象的,但是对象是具体的
类是对象的模板,对象是类的实体
一个类包括成员变量和成员方法
类的重要性:它是Java程序的基本组成单位
类的组成:属性和行为
属性:在类中通过成员变量来体现
行为:在类中通过成员方法来体现
对象的使用:
类名 对象名 = new 类名();
对象访问类成员:
对象名.成员变量
对象名.成员方法
//定义一个类
class A1 {
//成员变量
public int a;
public int b;
//无参构造方法 系统默认具有的构造方法,可以不写
public A1() {
}
//有参构造方法
public A1(int x, int y) {
System.out.println(x + " " + y);
}
//方法
public void run() {
System.out.println("类中的方法");
}
}
public class HelloWorld {
public static void main(String[] args) {
//创建对象来调用类中的成员变量以及方法
A1 a1 = new A1();//使用的是无参构造方法
a1.run();
A1 a2 = new A1(1, 2);//使用有参的构造方法
a2.run();
}
}
/**
* 定义一个学生信息类
* 记录学生信息
*/
class StudentInformation{
private Integer id;
private Integer age;
private String stu_name;
private Double score;
public StudentInformation(){}
public StudentInformation(Integer id, Integer age, String stu_name, Double score) {
this.id = id;
this.age = age;
this.stu_name = stu_name;
this.score = score;
}
@Override
public String toString() {
return "StudentInformation{" +
"id=" + id +
", age=" + age +
", stu_name='" + stu_name + '\'' +
", score=" + score +
'}';
}
}
public class Main {
public static void main(String[] args) {
StudentInformation studentInformation =new StudentInformation(1,20,"小白",99.5);
System.out.println(studentInformation.toString());
}
}
成员变量和局部变量
成员变量:类中方法外的变量
局部变量:方法中的变量
二者区别:
- 类中的位置不同(成员变量在类中方法外,局部变量在方法内或声明里)
- 内存的位置不同(成员变量在堆内存,局部变量在栈内存)
- 生命周期不同 (成员变量是随着对象的存在而存在,随着对象消失而消失, 局部变量则随着方法调用而存在,随着方法结束而消失)
- 初始化值不同(成员变量有默认的初始化值,局部变量没有默认的初始化值,必须先定义赋值才能使用)
private关键字:
- 是一个权限修饰符,可以修饰成员变量和成员方法,作用是保护成员不被别的类使用,被private修饰的成员只在本类中才能访问。
- 针对private修饰的成员变量,如果需要被其他类使用,则需要提供相应的操作,需要提供public修饰的set()、get()方法
this关键字:
- this修饰的变量用于指代成员变量
- 方法形参与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
- 方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量
为什么用this?为了解决局部变量隐藏成员变量
this代表所在类的对象引用,方法被哪个对象调用,this就代表哪个对象
构造方法:
构造方法是一种特殊的方法,作用创建对象
格式:public class 类名{
修饰符 类名(参数){ }
}
一旦给出构造方法,系统则不提供默认的构造方法。
如果定义了带参构造方法,还要使用无参构造方法,就必须再写一个无参构造方法
/**
* 定义一个学生信息类
* 记录学生信息
*/
class StudentInformation {
//下面四个变量都是成员变量
private Integer id;
private Integer age;
private String stu_name;
private Double score;
public StudentInformation() {
}
public StudentInformation(Integer id, Integer age, String stu_name, Double score) {
this.id = id;
this.age = age;
this.stu_name = stu_name;
this.score = score;
}
//方法里的变量 局部变量
public void Method() {
int i;
//i=10;
System.out.println(i);//程序会报错,因为局部变量没有默认的初始化值,需要赋值
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getStu_name() {
return stu_name;
}
public void setStu_name(String stu_name) {
this.stu_name = stu_name;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public String toString() {
return "StudentInformation{" +
"id=" + id +
", age=" + age +
", stu_name='" + stu_name + '\'' +
", score=" + score +
'}';
}
}
public class Main {
public static void main(String[] args) {
//成员变量都有默认的初始化值
StudentInformation studentInformation = new StudentInformation();
//打印结果为:StudentInformation{id=null, age=null, stu_name='null', score=null}
System.out.println(studentInformation.toString());
// studentInformation.id=1; //程序报错 因为是私有成员变量,不能直接访问
// studentInformation.age=20; //程序报错
//类中有public的set、get方法就可以获取或者设置成员变量的值
//this代表对象studentInformation
studentInformation.setId(1);
studentInformation.setAge(20);
}
}
封装:
面向对象三大特征(封装,继承,多态)
封装是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作的
封装原则:
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的set、get方法
封装的好处:
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性