本文我们来讲一讲Java面向对象三大特征之一的封装。
封装的概述
- 封装是面向对象编程的基本原则之一。
它指的是将对象的状态(属性)和行为(方法)打包在一起,并对外隐藏对象的内部实现细节。 - 主要目的:确保了数据的安全性和一致性,同时提供统一的访问接口。
- 主要功能:在于我们能够做到 “只修改自己类中的实现代码,而不用修改调用类对象的程序片段。”
- 访问修饰符
在Java中,封装通过访问修饰符(private、protected、public)来实现。下面是访问修饰符的访问范围表。

- 简单来说封装就是,通过将类的某些部分设置为私有,可以防止外部直接访问这些部分,从而保护对象的状态不被外部错误地修改。
实现封装的步骤
- 修改属性的访问权限来限制外界对属性的访问。(一般限制为private)
public class Person {private String name;private int age;}
例如这里的name和age都被private,只有本类可以直接访问,外界是直接访问不了的
- 对每种属性都提供对外的公共方法访问,也就是创建它们各自的get函数和set函数,用来访问、设定属性的值。
public class Person{private String name;private int age;public int getAge(){return age;}public String getName(){return name;}public void setAge(int age){this.age = age;}public void setName(String name){this.name = name;}
}
采用this关键字可以解决set中实例变量与局部变量同名冲突的问题。
封装的特点
封装的封闭性与信息隐藏:
通过将类的内部数据和实现细节对外隐藏起来,只提供有限的访问接口。
- 封闭性:
避免外部直接访问和修改内部数据,提高代码的安全性和稳定性。 - 信息隐藏:
防止外部依赖于类的内部结构,减少了外部对内部实现的依赖,提高了代码的灵活性和可维护性。
public class Person{private String name;private int age;public int getAge(){return age;}public String getName(){return name;}public void setAge(int age){this.age = age;}public void setName(String name){this.name = name;}
}
public class Main {public static void main(String[] args) {Person person = new Person();person.setName("John");person.setAge(25);System.out.println("Name: " + person.getName());System.out.println("Age: " + person.getAge());}
}
在上面的示例中,Person类封装了一个人的属性:name和age。
这两个属性被声明为私有的,外部无法直接访问。
通过提供公共的getter和setter方法,外部代码可以通过这些方法来访问和修改name和age属性。
这样就实现了对数据的封装和保护,外部代码无法直接修改属性的值,必须通过类提供的接口来操作。
封装的数据保护
-
封装不仅可以隐藏数据的实现细节,还可以通过访问修饰符来限制对数据的访问和修改。
-
私有访问修饰符(private)用于修饰类的成员,表示只能在类的内部访问,外部无法直接访问。
通过将数据成员声明为私有的,可以有效保护数据的完整性和安全性,只允许通过类提供的接口进行访问和修改。
public class BankAccount {private double balance;public BankAccount(double initialBalance) {balance = initialBalance;}public double getBalance() {return balance;}public void deposit(double amount) {if (amount > 0) {balance += amount;}}public void withdraw(double amount) {if (amount > 0 && balance >= amount) {balance -= amount;}}
}public class Main {public static void main(String[] args) {BankAccount account = new BankAccount(1000.0);System.out.println("Initial balance: " + account.getBalance());account.deposit(Apologies for the incomplete response. Here's the continuation of the example:account.deposit(500.0);System.out.println("Balance after deposit: " + account.getBalance());account.withdraw(200.0);System.out.println("Balance after withdrawal: " + account.getBalance());}
}
在上面的示例中,BankAccount类封装了一个银行账户的属性:balance。
balance属性被声明为私有的,外部无法直接访问。
通过提供公共的getter和setter方法,外部代码可以通过这些方法来访问和修改balance属性。
在deposit方法和withdraw方法中,通过对输入值的校验和对balance的修改,确保了对balance的安全操作。
封装与继承
封装通过隐藏和保护数据,提供统一的访问接口,增强了代码的安全性和可维护性。
继承允许子类继承父类的属性和方法,实现了代码的重用和扩展。同时,继承的多层次性和方法重写使得代码的组织更加清晰和灵活。
下面是《Java面向对象三大特征》这几篇文章的参考链接:
(1) (2) (3) (4) (5)
(6) (7) (8) (9) (10)
(11) (12) (13) (14)