封装性、继承性、多态性是面向对象程序设计的三大特性,其中封装性是最重要的一个特性。
一、理解封装
1.定义
封装性指将对象的状态信息隐藏在对象的内部,不允许外部程序直接访问对象内部的状态信息,只有通过该类对外提供的方法才能实现对内部信息的操作和访问。
2.封装优点
- 隐藏类的实现细节
- 只能通过对外提供的方法进行数据的访问,限制对成员变量的不正当存取
- 降低耦合性,提高了代码的可维护性
一个对象中,成员变量是核心所在,反映对象的外部特征,一般不允许外部对象对其直接访问。
二、访问控制符的使用
Java提供了4种访问控制级别,发别通过public,protected,默认访问控制符 (default)、private来进行修饰
- public:public是公共的意思,被public修饰的成员可以被所有类访问
- protected:protected修饰的成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问
- default:如果在类的成员前没有任何访问控制符,则该成员处于默认访问状态。处于默认访问状态的成员,只能被同一个包中的其它类访问
- private:private修饰的成员只能被这个类本身访问,其它类(包括同一个包中的类、其他包中的类和子类)都无法访问private修饰的成员
访问控制符 | 同一个类中 | 同一个包中 | 不同包中的子类 | 不同包中的非子类 |
---|---|---|---|---|
public | ✔ | ✔ | ✔ | ✔ |
protected | ✔ | ✔ | ✔ | |
default | ✔ | ✔ | ||
private | ✔ |
访问控制符的使用应该注意以下两点:
- 访问控制符用于类的成员是否可以被其他类访问,对于局部变量,其作用域在局部变量所在的方法中,故局部变量不能使用访问控制符来修饰
- 程序设计中,成员的修饰符根据具体情况定
1.getter和setter方法封装成员变量
实现一个类时,公有数据或者不加保护的数据是非常危险的,所以一般情况下应该将数据设为私有,然后通过方法操作数据
public class PeopleInstance {
public static void main(String[] args) {
Person person = new Person("小红", 12);
person.selfInfo();
Person p2 = new Person();
// p2.name="王名";
// p2.age=12;
p2.selfInfo();
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public void selfInfo() {
System.out.println(name);
System.out.println(age);
}
}
输出结果:
小红
12
null
0
Person的两个成员变量被私有化,只有在本类中才能被访问。外部类PeopleInstance中被注释掉的部分直接访问是错误的。person 的两个成员变量通过带两个参数的构造方法完成了初始化,能够得到正确的输出结果,而p2调用的是无参的构造方法完成的实例化,因为没有正确初始化,运行结果会取默认值,要想直接获取,可以通过各自对应的getter和setter方法来操作和访问这两个成员变量。快捷键alt+Insert一键生成:
public class PeopleInstance {
public static void main(String[] args) {
Person person = new Person("小红", 12);
person.selfInfo();
Person p2 = new Person();
// p2.name="王名";
// p2.age=12;
p2.selfInfo();
p2.setName("小明");
p2.setAge(12);
p2.selfInfo();
}
}
class Person {
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;
}
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public void selfInfo() {
System.out.println(name);
System.out.println(age);
}
}
输出结果:
小红
12
null
0
小明
12
2.封装方法
方法一般情况下都设计成公有的,根据需要设计成私有的,私有方法不会被外部类操作,既保证了安全性,有能根据需要删除。如果希望子类来重写父类的一个方法,此时用protected修饰。
设计一个一元一次方程的类,并能根据系数情况求解方程
/**
* @Author:
* @Time: 2021/7/4 23:11
* @Description 设计一个一元一次方程的类,根据系数情况求解方程
* y=ax+b(考虑a的情况)
*/
class Equation {
private float a;
private float b;
public float getA() {
return a;
}
public void setA(float a) {
this.a = a;
}
public float getB() {
return b;
}
public void setB(float b) {
this.b = b;
}
Equation() {
}
public Equation(float a, float b) {
this.a = a;
this.b = b;
}
public boolean hasRoot() {
return a != 0;
}
public void show() {
if (hasRoot()) {
System.out.println("x= " + (-b / a));
} else {
if (b == 0) {
System.out.println("x=" + 0);
} else {
System.out.println("无解");
}
}
}
}
public class TestEquation {
public static void main(String[] args) {
Equation e1 = new Equation(2, 4);
e1.show();
Equation e2 = new Equation(1.1f, 2.2f);
e2.show();
Equation e3 = new Equation(0, 1);
e3.show();
Equation e4 = new Equation(0, 0);
e4.show();
}
}
输出结果:
x= -2.0
x= -2.0
无解
x=0
3.单例模式
- 定义:一个始终只创建一个实例的类,这个类被称为单例类,该类的构造器用private修饰
- 非单例类缺点:类的构造器大多数时候定义成public的,允许任何类自由创建该类的对象,但是在某些时候,允许其他类自由创建该类的对象没有任何意义,还可能因为频繁的创建以及回收对象造成系统性能下降
- 单例类中,一旦把构造器私有化,就需要向外部提供一个静态的方法(因为调用该方法前不存在对象,因此它只能是静态的)来获取一个对象实例。
/**
* @Author:
* @Time: 2021/7/4 23:45
* @Description
*/
class Singleton {
private static Singleton s;
private Singleton() {
}
public static Singleton getInstance() {
if (s == null) {
s = new Singleton();
}
return s;
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1==s2);
}
}
输出结果为true。单例设计模式能够保证一个类只创建一个实例,节省了因重复创建对象所带来的内存消耗,从而提高效率。
三、包
1.创建包的好处
- 不同功能的类可以使用相同的类名,只要分包处理
- 功能相似,接口组织在一个包中,便于查找和使用
- 提供访问权限的控制机制,拥有包访问权限的类才能访问包中的类
2.包命名规则
- 符合标识符命名规则
- 小写字母,一个或多个单词连接,单词之间使用"."连接
- 包名常用公司名或公司网址的逆序排列而成,如com.sun.swing
3.Java常用包
- java.lang:包含Java语言核心类,如String,Math,System,Thread
- java.util:包含一些实用工具类/接口/接口和集合框架类,如Arrays,List以及与日期日历相关的类
- java.io:包含Java输入/输出功能的类
- java.awt:用来构建图形用户界面GUI
- java.swing:包含Swing图形用户界面相关的类/接口
- java.text:包含Java格式化相关的类
- java.sql:包含Java进行JDBC数据库编程的相关类/接口