1. 类和对象基础
1.1 类的定义
定义类的格式:
class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
类中包含的内容称为类的成员
属性主要是用来描述类的,称之为类的成员属性或者字段
方法主要说明类具有哪些功能,称为类的成员方法
例子:
class Dog {
// 字段 / 属性 / 成员变量
public String name;
public int age;
// 行为 / 成员方法
public static void bark() {
System.out.println("汪");
}
}
注意:
类名注意采用大驼峰定义
1.2 类的实例化
什么是类的实例化?
使用class定义出的类,相当于创建了一个新的类型
使用这个类类型创建对象的过程,叫做类的实例化,如下例
// 1. 类的定义
class Dog {
// 字段 / 属性 / 成员变量
public String name;
public int age;
// 行为 / 成员方法
public static void bark() {
System.out.println("汪");
}
}
public class TestDemo {
public static void main(String[] args) {
// 2. 类实例化对象
Dog d1 = new Dog();
}
}
对象中存储什么?
对象存储属性/成员变量
new关键字实例化对象,具体执行过程是什么 ?
1.3 对象属性和方法的访问
// 1. 类的定义
class Dog {
// 字段 / 属性 / 成员变量
public String name;
public int age;
// 行为 / 成员方法
public static void bark() {
System.out.println("汪");
}
}
public class TestDemo {
public static void main(String[] args) {
// 2. 类实例化对象
Dog d1 = new Dog();
// 3. 访问对象属性与方法
d1.age = 10;
d1.name = "大黄";
System.out.println(d1.name);
System.out.println(d1.age);
d1.bark();
}
}
Dog d1 = new Dog();
局部变量 d1 -> 因为存储对象在堆上的地址 -> 叫做引用变量,简称引用
使用 引用(对象地址).属性 访问对象的成员变量
使用 引用(对象地址).方法 访问对象的成员方法
下面使用类和对象知识,交换两个值
class MyValue {
int value;
}
public class TestDemo {
public static void main(String[] args) {
MyValue num1 = new MyValue();
MyValue num2 = new MyValue();
num1.value = 1;
num2.value = 2;
System.out.printf("交换前 ---> num1 = %d num2 = %d\n",num1.value,num2.value);
Swap(num1,num2);
System.out.printf("交换后 ---> num1 = %d num2 = %d\n",num1.value,num2.value);
}
public static void Swap(MyValue num1, MyValue num2) {
int tmp = num1.value;
num1.value = num2.value;
num2.value = tmp;
}
}
2. this引用
2.1 问题引入
class Date {
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day) {
year = year;
month = month;
day = day;
}
public void print() {
System.out.print(year + " " + month + " " + day);
}
}
public class TestDemo {
public static void main(String[] args) {
Date date1 = new Date();
date1.setDate(2023,11,5);
date1.print();
}
}
date1.setDate(); 这段代码是如何对date1引用指向的对象进行赋值的 ?
date1.print(); 这段代码为什么会打印 2023 11 5?
解:
3. 构造方法
3.1 什么是构造方法
构造方法是一个特殊的成员方法,用来对对象的属性/成员变量进行初始化
构造方法写法 :名字与类 名相同,没有返回值类型,如图
3.2 构造方法的注意点
1. new创建对象时,首先给对象分配内存,然后编译器自动调用合适的构造方法给对象进行初始化 这里的合适指,编译器会根据参数选取构造方法进行初始化,如图
2. 如果没有自己定义构造方法,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参。如果自己定义了构造方法,编译器将不再生成
3. 构造方法可以重载
4. 构造方法中,可以通过this调用其他构造方法
注意: 使用this调用必须放在当前构造方法的第一行,this调用也是根据参数选取构造方法进行调用,如图
class Date {
public int year;
public int month;
public int day;
public Date(int y,int m,int d) {
this.year = y;
this.month = m;
this.day = d;
}
public Date() {
/*this.year = 1;
this.month = 1;
this.day = 1;*/
// 调用带有3个参数的构造方法
this(2,2,2);
}
public void print(Date this) {
System.out.print(this.year + " " + this.month + " " + this.day);
System.out.println();
}
}
public class TestDemo {
public static void main(String[] args) {
Date date1 = new Date(2023,11,5);
Date date2 = new Date();
//date1.setDate(2023,11,5);
date1.print();
date2.print();
}
}
4. 封装
4.1 什么是封装
观察下面这个例子
为什么会报错 ?
那么,如何才能访问name属性 ?
同理,当一个成员方法被private修饰时,同样无法使用对象的引用访问对象的方法
当构造方法被private修饰时,同样只能在类中调用
接下来的问题是,什么是封装 ?
4.2 总结
什么是封装 ?
在java中,封装是使用private关键字对类实现细节进行隐藏
为什么要有封装 ?
private修饰成员变量/方法后,无法在类外访问成员变量/方法,提高安全性
5. static 成员
5.1 static修饰成员变量
成员变量被static关键字修饰会发生什么 ?观察下面两张图
class Student {
private String name;
private int age;
public String classRoom;//上课的教室
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 getClassRoom() {
return classRoom;
}
public void setClassRoom(String classRoom) {
this.classRoom = classRoom;
}
}
public class TestDemo {
public static void main(String[] args) {
Student stu1 = new Student("a",18);
Student stu2 = new Student("b",19);
stu1.setClassRoom("222");
stu2.setClassRoom("222");
}
}
未加static:
加static:
通过观察发现,当classRoom成员变量被static修饰后,classRoom这个成员变量已经不在对象中了,不再属于对象,而是属于类的属性 存储在方法区,如下图
由于static修饰的成员变量属于类,所以需要使用 类名+点号访问 静态成员变量(static修饰的成员变量)
注意:
1. 虽然使用类实例化对象的引用也可以访问静态成员变量,但是不合适不建议
2. 注意区分静态成员变量和非静态成员变量
静态成员:
属于类的属性,存储在方法区 且只存储一份
使用类名+点号 访问静态成员变量
非静态成员变量:
属于对象,每个对象在实例化后 都会有一个非静态成员变量 存储在堆区
使用对象的引用+点号 访问静态成员变量
3. 静态的成员变量 随着类被加载而创建 类被销毁而销毁
5.2 static修饰成员方法
成员方法被static关键字修饰会怎么样?
当static修饰成员方法eat后 无法在使用this引用 这是为什么?
和静态成员变量相同,当成员方法被static修饰后 这个静态成员方法是属于类的 不属于对象,所以 不是用对象的引用调用静态成员变量,也就不会传递this引用
因为不会传递this引用,所以在静态方法中都不能使用this引用和非静态成员变量