编程自学指南:java程序设计开发,类的封装详解
一、课程信息
学习目标
- 理解类的封装概念和重要性。
- 掌握使用访问修饰符实现类的封装。
- 学会通过 getter 和 setter 方法访问和修改私有属性。
- 能够运用封装原则设计和实现简单的 Java 类。
课程重点
- 封装的概念和作用。
- 访问修饰符的使用。
- getter 和 setter 方法的编写。
课程难点
- 如何合理运用封装来提高代码的安全性和可维护性。
- 理解封装在面向对象编程中的核心地位。
二、课程导入
生活中的封装实例
在生活中,我们经常会遇到封装的概念。比如,手机就是一个很好的例子。手机内部有复杂的电路、芯片等组件,但我们使用手机时,并不需要了解这些内部细节,只需要通过手机提供的按键、屏幕等接口来操作即可。这就是一种封装,将内部的实现细节隐藏起来,只对外提供简单的操作接口。
编程中的问题引入
在没有封装的情况下,我们可能会写出这样的代码:
class Student {
String name;
int age;
}
public class WithoutEncapsulation {
public static void main(String[] args) {
Student student = new Student();
student.name = "Tom";
student.age = -10; // 这里年龄设置为负数,不符合实际情况
System.out.println("Name: " + student.name + ", Age: " + student.age);
}
}
在这个例子中,Student
类的属性 name
和 age
是公开的,外部代码可以直接访问和修改它们,这可能会导致数据的不一致性和安全性问题。
三、封装的概念
什么是封装
封装是面向对象编程的三大特性之一,它是指将对象的状态信息(属性)隐藏在对象内部,不允许外部程序直接访问,而是通过该对象提供的方法来实现对这些属性的操作和访问。
封装的作用
- 提高数据的安全性:可以防止外部代码随意修改对象的属性,避免数据被非法篡改。
- 提高代码的可维护性:将内部实现细节隐藏起来,当内部实现发生变化时,只要对外提供的接口不变,外部代码就不需要修改。
- 增强代码的复用性:封装好的类可以在不同的地方重复使用,提高开发效率。
四、访问修饰符
访问修饰符的种类
Java 提供了四种访问修饰符,用于控制类、属性和方法的访问权限:
public
:公共的,被public
修饰的类、属性和方法可以被任何类访问。private
:私有的,被private
修饰的属性和方法只能在本类中访问。protected
:受保护的,被protected
修饰的属性和方法可以在本类、同一个包中的其他类以及不同包中的子类中访问。- 默认(无修饰符):也称为包访问权限,被默认修饰的类、属性和方法只能在同一个包中的其他类访问。
示例代码
// 公共类
public class PublicClass {
public String publicField; // 公共属性
private int privateField; // 私有属性
protected double protectedField; // 受保护属性
String defaultField; // 默认属性
public void publicMethod() {
System.out.println("This is a public method.");
}
private void privateMethod() {
System.out.println("This is a private method.");
}
protected void protectedMethod() {
System.out.println("This is a protected method.");
}
void defaultMethod() {
System.out.println("This is a default method.");
}
}
// 同一个包中的其他类
class AnotherClassInSamePackage {
public static void main(String[] args) {
PublicClass obj = new PublicClass();
obj.publicField = "Hello";
// obj.privateField = 10; // 编译错误,不能访问私有属性
obj.protectedField = 3.14;
obj.defaultField = "World";
obj.publicMethod();
// obj.privateMethod(); // 编译错误,不能访问私有方法
obj.protectedMethod();
obj.defaultMethod();
}
}
五、使用封装实现类
步骤
- 将属性声明为私有:使用
private
修饰符将类的属性隐藏起来。 - 提供公共的 getter 和 setter 方法:通过 getter 方法获取属性的值,通过 setter 方法设置属性的值。
示例代码
class Student {
private String name;
private int age;
// getter 方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
// setter 方法
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
if (age >= 0 && age <= 150) {
this.age = age;
} else {
System.out.println("Invalid age!");
}
}
}
public class EncapsulationExample {
public static void main(String[] args) {
Student student = new Student();
student.setName("Alice");
student.setAge(20);
System.out.println("Name: " + student.getName() + ", Age: " + student.getAge());
student.setAge(-10); // 会输出 "Invalid age!"
}
}
在这个例子中,Student
类的 name
和 age
属性被声明为私有,外部代码不能直接访问它们。通过 getName()
和 getAge()
方法可以获取属性的值,通过 setName()
和 setAge()
方法可以设置属性的值。在 setAge()
方法中,我们添加了年龄的合法性检查,确保年龄在合理范围内。
六、封装的优点示例
安全性提升
通过封装,我们可以对属性的访问进行控制,避免非法数据的输入。如上面 Student
类的 setAge()
方法,防止了年龄被设置为负数。
可维护性提升
假设 Student
类的 age
属性存储方式发生变化,从 int
类型改为 LocalDate
类型(存储出生日期),只要 getAge()
和 setAge()
方法的接口不变,外部代码就不需要修改。
import java.time.LocalDate;
import java.time.Period;
class Student {
private String name;
private LocalDate birthDate;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
LocalDate currentDate = LocalDate.now();
return Period.between(birthDate, currentDate).getYears();
}
public void setAge(int age) {
LocalDate currentDate = LocalDate.now();
this.birthDate = currentDate.minusYears(age);
}
}
复用性提升
封装好的类可以在不同的项目或模块中重复使用。例如,我们可以将 Student
类用于学生管理系统、学校考勤系统等多个项目中。
七、课堂练习
练习 1
创建一个 BankAccount
类,包含私有属性 accountNumber
(账号)、balance
(余额)。提供公共的 getter 和 setter 方法,在 setBalance()
方法中确保余额不能为负数。
练习 2
创建一个 Book
类,包含私有属性 title
(书名)、author
(作者)、price
(价格)。提供公共的 getter 和 setter 方法,在 setPrice()
方法中确保价格不能为负数。
八、课程总结
重点回顾
- 封装的概念和作用。
- 四种访问修饰符的使用。
- 通过 getter 和 setter 方法实现封装。
- 封装对代码安全性、可维护性和复用性的提升。
注意事项
- 在设计类时,要合理使用访问修饰符,尽量将属性声明为私有,提供公共的访问方法。
- 在 setter 方法中,要对输入的数据进行合法性检查,确保数据的一致性和安全性。
九、课后作业
作业 1
创建一个 Employee
类,包含私有属性 employeeId
(员工编号)、name
(姓名)、salary
(工资)。提供公共的 getter 和 setter 方法,在 setSalary()
方法中确保工资不能低于当地最低工资标准(假设为 2000)。
作业 2
设计一个 Rectangle
类,包含私有属性 length
(长)和 width
(宽)。提供公共的 getter 和 setter 方法,同时提供计算矩形面积和周长的方法。