主题
Java面向对象核心:类与对象、封装、构造方法与static关键字
一、核心知识点
1. 匿名对象
1.1 概念
匿名对象是指没有名字的对象,只有 new 对象(),没有等号左边的部分。
java
Person p = new Person(); // 有名对象
new Person(); // 匿名对象1.2 使用方式
java
new 类名().成员名;1.3 注意事项
- 如果涉及到赋值,千万不要用匿名对象
- 使用场景:简单调用一个方法,让方法执行一次
1.4 代码示例
java
public class Person {
String name;
public void eat(){
System.out.println("吃饭");
}
}
public class Demo01Object {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "张三";
System.out.println(p1.name);
p1.eat();
System.out.println("==================");
new Person().eat();
new Person().name = "李四";
System.out.println(new Person().name);
}
}
2. 对象内存图解
2.1 一个对象的内存图
java
public class Phone {
String brand;
int price;
public void call(){
System.out.println("打电话");
}
}
public class Demo01Object {
public static void main(String[] args) {
Phone phone1 = new Phone();
System.out.println(phone1);
System.out.println(phone1.brand);
System.out.println(phone1.price);
phone1.brand = "华为";
phone1.price = 8888;
System.out.println(phone1.brand);
System.out.println(phone1.price);
phone1.call();
}
}
2.2 两个对象的内存图
new了两次对象,在堆内存中开辟了两个不同的空间,修改一个空间中的数据不会影响到另外一个空间的数据。

2.3 两个对象指向同一片空间
phone2是phone1给的,会将phone1的地址值给phone2,此时phone1和phone2地址值是一样的,操作同一个空间中的数据,所以修改一个对象的数据会影响另外一个对象。

3. 成员变量与局部变量
| 区别 | 成员变量 | 局部变量 |
|---|---|---|
| 定义位置 | 类中方法外 | 方法内或形参位置 |
| 初始化值 | 有默认值 | 没有默认值,必须手动赋值 |
| 作用范围 | 整个类 | 只作用于自己方法内部 |
| 内存位置 | 堆中 | 栈中 |
| 生命周期 | 随对象创建而创建,随对象消失而消失 | 随方法执行而创建,随方法消失而消失 |
java
public class Person {
String name;
public void eat() {
System.out.println(name);
int i = 10;
System.out.println(i);
}
public void show() {
System.out.println(name);
}
}4. 封装
4.1 面向对象三大特征
- 封装
- 继承
- 多态
4.2 封装概述
隐藏细节(不让外界随便调用),对外提供公共的接口(让外界通过这个公共接口间接使用封装起来的细节)。
4.3 private关键字
被private修饰的成员只能在本类中直接使用,别的类中不能直接使用。
4.4 公共接口:get/set方法
| 方法 | 作用 |
|---|---|
| getxxx() | 获取属性值 |
| setxxx() | 为属性赋值 |
java
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
5. this关键字
5.1 概述
代表当前对象(哪个对象调用的this所在的那个方法,this就代表哪个对象)。
5.2 作用
区分重名的成员变量和局部变量,this.后面的就是成员变量。
java
public class Person {
String name;
public void speak(String name){
System.out.println(this.name+"您好,我是"+name);
}
}
6. 构造方法
6.1 特点
- 方法名和类名一致
- 构造方法没有返回值,连void都没有
- 一new就相当于调用了构造方法
6.2 空参构造
java
public 类名(){
}作用:new对象,初始化对象的属性
特点:每个类中都默认有一个无参构造,即使不写,jvm也会默认提供一个
6.3 有参构造
java
public 类名(形参){
为属性赋值
}作用:
- new对象
- 为属性赋值
注意:如果写了有参构造,jvm将不再提供无参构造,所以建议无参的、有参的构造都写出来
6.4 代码示例
java
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
7. 标准JavaBean
7.1 规范要求
- 类必须是具体的(非抽象 abstract)和公共的,
public class 类名 - 具有无参数的构造方法
- 成员变量私有化,并提供用来操作成员变量的set和get方法
7.2 标准代码示例
java
public class Student {
private int sid;
private String name;
public Student() {
}
public Student(int sid, String name) {
this.sid = sid;
this.name = name;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}7.3 快捷键生成
通用快捷键:alt+insert 或 alt+fn+insert

8. static关键字
8.1 概述
static是静态关键字,可以修饰方法和成员变量。
修饰方法:
java
权限修饰符 static 返回值类型 方法名(形参){
方法体
return 结果
}修饰成员变量:
java
权限修饰符 static 数据类型 变量名8.2 特点
| 特点 | 说明 |
|---|---|
| 归属 | 静态成员属于类成员,不属于对象成员 |
| 加载时机 | 静态成员会随着类的加载而加载 |
| 优先级 | 静态成员优先于对象存在 |
| 共享性 | 凡是根据static关键字所在的类创建出来的对象,都可以共享这个静态成员 |
8.3 代码示例
java
public class Student {
int id;
String name;
static String classRoom;
}
public class Demo01Static {
public static void main(String[] args) {
Student.classRoom = "教研室6";
Student s1 = new Student();
s1.id = 1;
s1.name = "张三";
System.out.println(s1.id+"..."+s1.name+"..."+Student.classRoom);
Student s2 = new Student();
s2.id = 2;
s2.name = "李四";
System.out.println(s2.id+"..."+s2.name+"..."+Student.classRoom);
}
}
8.4 static成员访问特点
| 场景 | 能否直接访问 | 访问方式 |
|---|---|---|
| 静态方法中访问非静态成员 | 不能 | new对象访问 |
| 静态方法中访问静态成员 | 能 | 同类直接调用,不同类类名调用 |
| 非静态方法中访问静态成员 | 能 | 同类直接调用,不同类类名调用 |
| 非静态方法中访问非静态成员 | 能 | 同类直接调用,不同类new对象调用 |
8.5 使用场景
工具类:拥有多个通用性功能的类
工具类要求:
- 构造私有化
- 成员都是静态的
java
public class ArrayTools {
private ArrayTools(){}
public static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
}
public class Test01 {
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
System.out.println(ArrayTools.getSum(arr));
}
}二、常见面试题
⭐ 基础题
Q1: 匿名对象的使用场景是什么?什么情况下不能使用匿名对象?
答:
- 使用场景:简单调用一个方法,让方法执行一次
- 不能使用的情况:涉及到赋值操作时,因为每次new都会创建新对象,赋值后无法获取
Q2: 成员变量和局部变量有什么区别?
答:
| 区别 | 成员变量 | 局部变量 |
|---|---|---|
| 定义位置 | 类中方法外 | 方法内或形参位置 |
| 初始化值 | 有默认值 | 没有默认值,必须手动赋值 |
| 作用范围 | 整个类 | 只作用于自己方法内部 |
| 内存位置 | 堆中 | 栈中 |
| 生命周期 | 随对象创建而创建 | 随方法执行而创建 |
Q3: private关键字的作用是什么?
答:被private修饰的成员只能在本类中直接使用,别的类中不能直接使用,实现了封装的隐藏细节功能。
⭐⭐ 进阶题
Q4: this关键字的作用是什么?
答:
- 代表当前对象(哪个对象调用的this所在的那个方法,this就代表哪个对象)
- 可以区分重名的成员变量和局部变量,this.后面的就是成员变量
Q5: 构造方法有什么特点?空参构造和有参构造的作用分别是什么?
答:
- 特点:方法名和类名一致;没有返回值,连void都没有;一new就相当于调用构造方法
- 空参构造:new对象,初始化对象的属性
- 有参构造:new对象的同时为属性赋值
Q6: 如果写了有参构造,还需要写空参构造吗?为什么?
答:需要。如果写了有参构造,jvm将不再提供无参构造。如果后续需要使用空参构造创建对象,就会报错,所以建议都写出来。
Q7: 有参构造可以new对象并为属性赋值,那还需要set方法吗?
答:需要。如果我们要单独修改一个属性的值,没有必要重新new对象,直接利用对象的set方法就可以单独为属性改值。
⭐⭐⭐ 高级题
Q8: static关键字有什么特点?静态成员什么时候使用?
答:
- 特点:
- 静态成员属于类成员,不属于对象成员
- 静态成员会随着类的加载而加载
- 静态成员优先于对象存在
- 同一个类的所有对象共享静态成员
- 使用场景:定义工具类时,工具类中的成员都是静态成员
Q9: 在静态方法中能否直接访问非静态成员?为什么?
答:不能。因为静态成员随着类的加载而加载,优先于对象存在。非静态成员属于对象,需要创建对象才能访问。在静态方法中想访问非静态成员,需要先new对象。
Q10: 什么是标准JavaBean?它有哪些规范要求?
答:JavaBean是Java语言编写类的一种标准规范。规范要求:
- 类必须是具体的(非抽象)和公共的
- 具有无参数的构造方法
- 成员变量私有化,并提供set和get方法
Q11: 两个对象指向同一片内存空间会有什么影响?
答:当一个对象将地址值赋给另一个对象时,两个对象指向同一片内存空间。此时修改一个对象的数据会影响另一个对象,因为它们操作的是同一片内存区域。
三、实用代码片段
1. 标准JavaBean模板
java
public class Student {
private int sid;
private String name;
public Student() {
}
public Student(int sid, String name) {
this.sid = sid;
this.name = name;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}2. 工具类模板
java
public class ArrayTools {
private ArrayTools(){}
public static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
}3. 封装使用示例
java
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
if(age < 0 || age > 120) {
System.out.println("年龄输入有误");
return;
}
this.age = age;
}
public int getAge() {
return age;
}
}四、经典练习题
练习1:定义生日类
题目:定义一个类MyDate,代表生日,类中定义三个属性,分别为year、month、day,并为三个属性赋值。
参考答案:
java
public class MyDate {
private int year;
private int month;
private int day;
public MyDate() {
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}练习2:定义公民类
题目:定义一个公民类Citizen,类中定义三个属性,分别为cardId(String)、name(String)、MyDate(MyDate),并为三个属性赋值。
注意:如果属性为自定义的类型,赋值时需要new对象赋值,不然直接调用时会出现空指针异常。
参考答案:
java
public class Citizen {
private String cardId;
private String name;
private MyDate birthday;
public Citizen() {
}
public Citizen(String cardId, String name, MyDate birthday) {
this.cardId = cardId;
this.name = name;
this.birthday = birthday;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
}
public class Test {
public static void main(String[] args) {
Citizen c = new Citizen();
c.setCardId("110101199001011234");
c.setName("张三");
c.setBirthday(new MyDate(1990, 1, 1));
System.out.println("身份证号:" + c.getCardId());
System.out.println("姓名:" + c.getName());
System.out.println("生日:" + c.getBirthday().getYear() + "年"
+ c.getBirthday().getMonth() + "月"
+ c.getBirthday().getDay() + "日");
}
}五、知识小结
核心要点速记
| 知识点 | 核心要点 |
|---|---|
| 匿名对象 | 没有名字的对象,只适合简单调用方法,不适合赋值 |
| 成员变量vs局部变量 | 位置、初始化、作用范围、内存、生命周期五方面区别 |
| 封装 | 隐藏细节,对外提供公共接口(get/set) |
| private | 私有访问权限,只能在本类中直接使用 |
| this | 代表当前对象,区分重名的成员变量和局部变量 |
| 构造方法 | 方法名与类名相同,无返回值,用于创建对象和初始化 |
| JavaBean | 公共类、无参构造、私有属性、get/set方法 |
| static | 静态成员属于类,随类加载,优先于对象,被所有对象共享 |
快捷键速查
| 功能 | 快捷键 |
|---|---|
| 生成构造方法/get/set | alt+insert 或 alt+fn+insert |
六、学习建议
- 理解内存模型:通过内存图理解对象的创建和引用传递,这是理解面向对象的基础
- 掌握封装思想:private + get/set 是封装的核心体现,理解为什么要隐藏细节
- 熟练使用this:this关键字在构造方法和set方法中使用频繁,要理解其代表"当前对象"的含义
- 区分static和非static:理解静态成员属于类,非静态成员属于对象的区别
- 多写标准JavaBean:这是Java开发中最常用的类结构,要能快速编写