封装是什么,Java封装的具体实现(附带实例)
封装性是面向对象编程的很重要的一种特性,所谓封装就是将内部细节包装起来,从外部看就是一个单一的整体。
对于 Java 而言,封装主要是指将 Java 类中的某些属性隐藏起来,从而防止被外部随意访问和修改,如果要访问则必须通过规定的方法,比如将某个类的属性 data 设置为 private,然后提供 setData() 和 getData() 两个方法来对其进行访问。
举个简单的例子:
测试类最终的输出为“the balance is 31.0”,对余额的修改操作只能通过 deposit() 和 withdraw() 这两个方法进行,这两个方法都对参数进行了校验,从而能确保余额不会被恶意修改。
下面看一下如果不考虑封装性会带来什么问题。假如有人恶意将参数 -10 传入取钱方法 withdraw(),如果没有做好封装后的数据校验则会导致余额增加的严重逻辑错误。
此外,如果没有将 balance 变量设置为 private,那么就可以直接随意修改余额,这会导致很严重的问题。
1) 将需要封装的类属性的访问修饰符改为 private 从而确保属性不能被外部随意访问,比如在下面实例的 Child 类中将 name 和 age 两个属性都设为 private。
2) 提供对每个属性访问和修改的方法,通过这些方法能够读取或修改属性值。例如:
要注意的是,这些方法名并没有规定一定要以
3) 对
对于 Java 而言,封装主要是指将 Java 类中的某些属性隐藏起来,从而防止被外部随意访问和修改,如果要访问则必须通过规定的方法,比如将某个类的属性 data 设置为 private,然后提供 setData() 和 getData() 两个方法来对其进行访问。
举个简单的例子:
class Account {
private double balance = 0;
public void withdraw(double num) {
if (num < 0)
System.out.println("error");
else
balance = balance - num;
}
public void deposit(double num) {
if (num < 0)
System.out.println("error");
else
balance = balance + num;
}
public double getBalance() {
return balance;
}
}
public class EncapsulationTest {
public static void main(String[] args) {
Account account = new Account();
account.deposit(20.5);
account.deposit(20.5);
account.withdraw(10);
System.out.println("the balance is " + account.getBalance());
}
}
程序中,Account 类代表一个账户类,该类中有一个声明为 private 的变量 balance,它表示账户余额。可以看到所有对 balance 变量的操作都通过方法来限制,并要按照一定的规则进行修改,而不能直接修改该变量,这就体现了封装性。测试类最终的输出为“the balance is 31.0”,对余额的修改操作只能通过 deposit() 和 withdraw() 这两个方法进行,这两个方法都对参数进行了校验,从而能确保余额不会被恶意修改。
下面看一下如果不考虑封装性会带来什么问题。假如有人恶意将参数 -10 传入取钱方法 withdraw(),如果没有做好封装后的数据校验则会导致余额增加的严重逻辑错误。
Account account = new Account(); account.withdraw(-10);
此外,如果没有将 balance 变量设置为 private,那么就可以直接随意修改余额,这会导致很严重的问题。
Account account = new Account(); account.balance = 10000;
Java封装的具体实现
如何实现封装性呢?需要通过下面三个步骤来实现。1) 将需要封装的类属性的访问修饰符改为 private 从而确保属性不能被外部随意访问,比如在下面实例的 Child 类中将 name 和 age 两个属性都设为 private。
public class Child {
private String name;
private int age;
}
2) 提供对每个属性访问和修改的方法,通过这些方法能够读取或修改属性值。例如:
public class Child {
private String name;
private int 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;
}
}
在实例程序中,Child 类提供了 getName()、setName()、getAge() 和 setAge() 这 4 个方法来分别访问和修改 name 和 age 这两个属性,我们通常称这些方法为 get() 方法和 set() 方法。要注意的是,这些方法名并没有规定一定要以
getxxx 和 setxxx 的形式,而可以根据实际需要进行命名。3) 对
setxxx 方法添加校验逻辑,从而保证属性的正确性。如果不需要则可以省略这一步。比如下面实例的 setAge() 方法中添加对负数的校验。
public class Child {
......
public void setAge(int age) {
if (age <= 0) {
System.out.println("年龄必须为正数");
return;
}
this.age = age;
}
}
总结
下面罗列了封装的几点好处:- 封装能减少代码间的耦合性,将各个类都封装好就能减少耦合性;
- 封装能提升数据的安全性,如果我们将属性封装起来就能有效避免属性值被随意修改;
- 封装能控制某些属性为只读或只写,比如只提供 getxxx 方法则为只读;
- 封装能有效提升代码的复用率;
- 封装有利于测试,我们将类封装好后能更方便地进行测试。
ICP备案:
公安联网备案: