上文对JAVA中的封装概念做了简单描述,本文继续对封装的概念做进一步研究。
一、封装的目的
封装的概念在生活中各处都有,其目的是因此事物内部的具体细节,而暴露出浅显易懂的、针对用户的操作方法。例如我们坐飞机,我们只需要考虑何时登机、坐的位置、何时离开,而不需要考虑发动机型号、雷达实现原理之类的问题,请看示例代码:
public class AirPlane{
//属性
private String brand;
private String radar;
int seatNum;
int boardingTime;
//方法
public void Board(){
System.out.println("正在登机...");
}
public void SearchSeat(){
System.out.println("寻找座位...");
}
}
上述例子中,定义了四个属性,其中brand和radar变量因为被private修饰,不能在别的类中被调用,而seatNum和boardTime变量由于默认值是default,在此类和同一包中的其它类中都可以被调用。
二、封装的基本原则
-
数据隐藏:
- 私有成员: 将对象的数据成员(字段、属性)声明为私有(private),这样它们只能在对象内部访问。
- 隐藏细节: 隐藏实现细节,使得对象的内部结构对外部是不可见的。
-
公有接口:
- 公有方法: 提供公有方法(public methods)来允许外部访问和操作对象的状态。
- 访问器方法: 使用访问器方法(getters)来获取对象的状态,使用修改器方法(setters)来修改对象的状态。
-
构造方法:
- 使用构造方法(constructor)来初始化对象的状态,确保对象在创建时就处于一个合法的和一致的状态。
- 构造方法在对象创建时自动调用,可以执行一些初始化操作。
-
不可变性:
- 在可能的情况下,使对象不可变,即对象的状态不能被修改。这有助于确保对象的一致性,并减少了一些并发问题。
-
例外情况的处理:
- 在某些情况下,可能需要提供一些更直接的访问方式,但这应该是有限的,并且需要谨慎使用。例如,提供受限制的访问器方法或特殊的访问权限。
-
尽量减少公有成员:
- 将成员变量声明为私有,通过公有方法提供对这些成员的访问和修改。尽量减少直接暴露成员变量,以提高封装的效果。
-
隐藏实现细节:
- 对外部只暴露必要的接口,隐藏内部的实现细节。这样,内部的修改不会影响外部使用。
-
良好命名和文档:
- 使用有意义的命名来描述公有方法的作用,提供清晰的文档,以便其他开发者了解如何正确使用对象。
三、访问修饰符
访问修饰符用于控制类、方法、变量等成员的可见性和访问权限。Java提供了四种主要的访问修饰符:
| 修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
|---|---|---|---|---|---|
| public | Y | Y | Y | Y | Y |
| protected | Y | Y | Y | Y/N | N |
| default | Y | Y | Y | N | N |
| private | Y | N | N | N | N |
注意事项:
- 类的访问修饰符: 类可以是
public或默认(包级别)。一个Java文件中最多只能有一个public类,并且类名必须与文件名相同。 - 接口的访问修饰符: 接口中的成员默认为
public,static,final,接口本身默认为public。 - 抽象类的访问修饰符: 抽象类可以是
public、protected、默认(包级别),但不能是private。抽象方法可以是public、protected、默认(包级别)。
四、私有变量和公有方法
私有变量和公有方法是面向对象编程中封装的一部分,其组合可以用于隐藏对象的内部实现细节,同时允许外部代码通过公有方法来访问和操作这些变量。这种方式有助于提高代码的安全性和可维护性。以下是私有变量和公有方法的基本概念和使用:
1、 私有变量(Private Variables):
私有变量是声明在类内部,但在类的外部不可直接访问的变量。通常使用 private 访问修饰符来声明私有变量。这样做的目的是防止外部直接访问和修改对象的内部状态。
javaCopy code
public class MyClass {
private int privateVariable;
// 构造方法
public MyClass(int initial) {
this.privateVariable = initial;
}
}
2、 公有方法(Public Methods):
公有方法是被设计为可以从类的外部访问的方法。通过这些公有方法,外部代码可以获取、修改或执行与对象相关的操作。这种方式允许类的内部实现发生变化,而不影响外部代码。
javaCopy code
public class MyClass {
private int privateVariable;
// 构造方法
public MyClass(int initial) {
this.privateVariable = initial;
}
// 公有方法
public int getPrivateVariable() {
return privateVariable;
}
public void setPrivateVariable(int newValue) {
this.privateVariable = newValue;
}
}
3、 使用私有变量和公有方法的优势:
- 数据隐藏: 外部无法直接访问私有变量,只能通过公有方法来获取或修改对象的状态,从而实现数据隐藏。
- 控制访问: 通过公有方法,可以更好地控制对对象内部状态的访问,确保操作是有效的。
- 灵活性: 内部实现细节的变化不会影响外部代码,提供了更大的灵活性和可维护性。
- 安全性: 防止外部直接访问和修改对象的内部状态,提高了代码的安全性。
示例代码:
javaCopy code
public class Main {
public static void main(String[] args) {
MyClass myObject = new MyClass(42);
// 通过公有方法访问私有变量
int value = myObject.getPrivateVariable();
System.out.println("Private Variable: " + value);
// 通过公有方法修改私有变量
myObject.setPrivateVariable(99);
System.out.println("Updated Private Variable: " + myObject.getPrivateVariable());
}
}
在这个例子中,通过 getPrivateVariable() 和 setPrivateVariable() 方法,外部代码可以访问和修改 MyClass 对象的私有变量 privateVariable。
五、构造方法
构造方法是一种特殊的方法,用于在创建对象时进行初始化操作。在Java中,构造方法的名称与类名相同,没有返回类型,并且在使用new关键字实例化对象时自动调用。构造方法通常用于设置对象的初始状态,为对象的属性赋初值等任务。以下是构造方法的一般形式:
public class Car {
private String model;
private int year;
// 无参数构造方法
public Car() {
model = "Unknown"; year = 0;
}
// 带参数的构造方法
public Car(String model, int year) {
this.model = model;
this.year = year;
}
// Getter和Setter方法等其他成员方法
}
// 使用无参数构造方法创建Car对象
Car myCar = new Car();
// 使用带参数构造方法创建Car对象
Car anotherCar = new Car("Toyota", 2022);
六、 封装的好处与注意事项
- 降低耦合度: 外部代码不依赖于内部实现细节,减少了代码的耦合度。
- 增加灵活性: 可以更方便地修改内部实现,而不影响外部代码。
- 提高代码可读性: 外部只需关注公共接口,使得代码更易于理解。
8、注意事项:
- 封装不是绝对的,有时需要权衡,确保公共接口足够灵活满足需求。
- 合理使用访问修饰符,不要滥用
public,以免破坏封装性。