引言:什么是面向对象编程?
面向对象编程(Object-Oriented Programming,OOP)是一种程序设计思想,它将程序中的数据和操作数据的方法组织在一起,形成"对象"。
想象一下现实世界:
- 汽车是一种"类",具体的某辆汽车(如车牌号"京A12345")是一个"对象"
- 学生是一种"类",具体某个学生"张三"是一个"对象"
- 银行账户是一种"类",具体某个账户是一个"对象"
面向对象的三大特征:
- 封装(Encapsulation):把数据和方法包装在一起
- 继承(Inheritance):类之间的关系
- 多态(Polymorphism):同一操作不同表现
类的定义
类(Class)是对象的模板或蓝图,它定义了对象应该具有的属性和方法。
类的基本结构
[访问修饰符] class 类名 {
// 属性(字段)
// 方法
}
一个完整的类示例
public class Student {
// ========== 属性(特征)==========
private String name; // 姓名
private int age; // 年龄
private int score; // 成绩
// ========== 构造方法 ==========
public Student() {
}
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
// ========== 方法(行为)==========
public void study() {
System.out.println(name + "正在学习...");
}
public void exam() {
System.out.println(name + "正在考试...");
score = score - 10;
System.out.println(name + "考试结束,成绩:" + score);
}
// ========== Getter和Setter ==========
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 int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + ", score=" + score + "}";
}
}
对象的创建和使用
创建对象
public class Main {
public static void main(String[] args) {
// 使用new关键字创建对象
Student student = new Student();
// 调用方法
student.setName("张三");
student.setAge(18);
student.setScore(100);
student.study();
student.exam();
System.out.println(student);
}
}
对象的内存模型
对象在内存中的存储
Student student = new Student();
student.setName("张三");
┌─────────────────────────────────┐
│ 堆内存(Heap) │
│ ┌─────────────────────────┐ │
│ │ Student对象 │ │
│ │ name: "张三" │ │
│ │ age: 18 │ │
│ │ score: 100 │ │
│ └─────────────────────────┘ │
└─────────────────────────────────┘
↑
│
student引用变量
(存储在栈内存中)
封装
封装是面向对象的第一大特征,它将数据和操作数据的方法包装在一起,对外提供接口,隐藏内部实现细节。
为什么要封装?
数据保护:防止外部随意修改重要数据
隐藏复杂性:外部不需要知道内部如何实现
易于维护:修改内部实现不影响外部使用
封装的实现:访问修饰符
| 修饰符 | 同类 | 同包 | 子类 | 任意位置 |
|---|---|---|---|---|
| private | ✓ | ✗ | ✗ | ✗ |
| (默认) | ✓ | ✓ | ✗ | ✗ |
| protected | ✓ | ✓ | ✓ | ✗ |
| public | ✓ | ✓ | ✓ | ✓ |
封装的实践
public class Person {
// 使用private隐藏数据
private String name;
private int age;
// 使用public方法提供访问接口
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
// 在setter中加入验证逻辑
public void setAge(int age) {
if (age < 0 || age > 150) {
System.out.println("年龄不合法!");
return;
}
this.age = age;
}
}
构造方法
构造方法是创建对象时调用的特殊方法,用于初始化对象。
构造方法的特点
方法名与类名相同
没有返回类型(连void都没有)
创建对象时自动调用
无参构造方法
public class Dog {
private String name;
// 如果不写构造方法,编译器会自动提供一个默认的无参构造方法
public Dog() {
System.out.println("无参构造方法被调用");
}
}
// 使用
Dog dog = new Dog(); // 调用无参构造方法
带参构造方法
public class Dog {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
// 使用
Dog dog = new Dog("旺财", 3);
构造方法重载
public class Dog {
private String name;
private int age;
private String color;
// 构造方法重载
public Dog() {
}
public Dog(String name) {
this.name = name;
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
}
this关键字
this关键字指向当前对象,用于区分成员变量和局部变量。
public class Person {
private String name;
public Person(String name) {
// this.name 表示对象的成员变量
// name 表示构造方法的参数(局部变量)
this.name = name;
}
public void setName(String name) {
// 同样用this区分
this.name = name;
}
}
重要规则:如果定义了带参构造方法,编译器就不会自动提供无参构造方法。如果需要,确保手动添加无参构造方法。
static关键字
static修饰的成员属于类,不属于对象。
静态变量(类变量)
public class Student {
private String name;
private static int studentCount = 0; // 所有学生对象共享
public Student(String name) {
this.name = name;
studentCount++; // 每创建一个学生,对象计数加1
}
public static int getStudentCount() {
return studentCount;
}
}
// 使用
Student s1 = new Student("张三");
Student s2 = new Student("李四");
System.out.println(Student.getStudentCount()); // 2
静态方法
public class MathHelper {
public static int max(int a, int b) {
return a > b ? a : b;
}
public static int min(int a, int b) {
return a < b ? a : b;
}
}
// 使用:不需要创建对象,直接类名.方法名调用
int max = MathHelper.max(10, 20);
int min = MathHelper.min(10, 20);
静态方法注意事项:
- 静态方法只能访问静态成员,不能访问实例成员
- 静态方法中不能使用this关键字
- 调用时使用类名.方法名()或直接方法名()
代码规范与最佳实践
类命名规范
// 正确的类名命名
public class Student {} // 名词,大写开头
public class UserAccount {} // 多个单词驼峰命名
public class ArrayList {} // 内部已存在,示例而已
// 错误的类名命名
public class student {} // 应该大写开头
public class student_info {} // 不应该用下划线
方法命名规范
public class User {
// 正确的方法命名
public void setName(String name) {} // 驼峰命名
public String getName() {}
public void calculateTotalPrice() {}
public boolean isActive() {} // 布尔类型用is开头
// 错误的命名
public void SetName(String name) {} // 不应该大写开头
}
小结
- 类是对象的模板,定义属性和方法;对象是类的实例
- 封装通过private隐藏数据,通过public方法提供访问接口
- 构造方法用于创建和初始化对象
- this关键字指向当前对象,用于区分成员变量和局部变量
- static修饰的成员属于类,所有对象共享
- 访问修饰符控制可见性:private < 默认 < protected < public
☕ Java 在线代码编辑器
📝 运行结果