什么是java中的封装(非常详细)

什么是java中的封装(非常详细)

封装就是将类的状态信息(属性)和行为(方法)包装在一个类中,并对类的属性设置访问权限,隐藏类的内部实现细节,只通过特定的方法来访问和修改这些属性。

通过封装,可以提高代码的安全性、可维护性和可扩展性。

Java包的使用

包(package)是一种用于组织和管理类、接口及其他程序元素的机制。

包的作用至少有以下几点:

避免命名冲突:在庞大的项目架构中,同名的类可能大量出现。我们通过将这些类分散在不同的包中,能够有效规避命名上的冲突。

提升组织性和管理效率:包的使用有助于将相关的类、接口及其他程序组件整合在一起,从而增强代码的可读性和可维护性。

精细化访问控制:包机制允许我们对类、接口及其他程序组件的访问权限进行精细控制。将特定的类置于特定的包内,可以限制其访问范围,确保只有授权的类能够访问。

1) 包声明

在 Java 源文件的起始部分,我们可以通过使用关键字 package 来声明源文件内类的归属包。

例如,语句“package com.chapter7.project;”表明源文件中的类是属于“com.chapter7. project”包的。

2) 包导入

当需要在一个类中引用另一个包的类时,可以借助关键字 import 来导入所需的类。

例如,语句“import com.chapter7.project.ClassTest;”实现了对“com.chapter7.project”包中 ClassTest 类的导入。

此外,我们还可以使用通配符导入一个包内的所有类,如“import com.chapter7. project*;”。

3) 自定义包

在文件系统中构建一个与包名相对应的目录结构。例如,如果要创建一个名为“com.company.myproject”的包,就应该在项目的根目录下创建一个 com 目录,接着在 com 目录下创建 company 目录,最后在 company 目录下创建 myproject 目录。

将 Java 源文件放置在相应的包目录内,并在源文件的起始处声明包名。

在其他 Java 源文件中,可以通过导入自定义包内的类来使用它们。只要自定义包位于项目的类路径中,Java 编译器和运行环境便能够定位并使用这些包中的类。

Java访问修饰符的权限

在不影响正常功能执行的前提下,应该尽可能使每个类或类中的成员可访问性最小。在 Java 编程语言中,控制成员(属性、方法、嵌套类)可访问性的关键字有 private(私有的)、default(默认)、protected(受保护的)及 public(公有的),如下表所示。

表:访问修饰符的访问权限

访问修饰符

当前类

同一包内

子孙类(同一包)

子孙类(不同包)

其他包

public

protected

√/X

X

default

X

X

private

X

X

X

X

下面按照可访问性范围递减进行说明:

public:对所有类可见。使用对象:类、接口、变量、方法;

protected:对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能使用修饰类(外部类);

default(默认,什么也不写):在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法;

private:在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)。

Java封装的实现

私有化(private)成员属性会使当前类无法被其他类友好使用,公有化(public)成员属性就失去了封装的意义。

如何保证类成员既不暴露数据域又能被其他类友好访问呢?我们通常将类设计为包含私有域属性(private)和公有访问方法(getter),如果需要对私有的属性进行初始化,就可以提供公有的方法(setter)。

【实例】创建一个 Person 类,属性分别是 age 和 name,将属性进行封装,并且进行初始化,在控制台输出结果,代码如下:

public class Person {

/* 定义全局属性,将属性进行封装 */

private int age;

private String name;

/* 将属性初始化,并提供 setter 方法 */

public void setAge(int age) {

this.age = age;

if (age > 20) {

System.out.println("大于 20 岁");

} else {

this.age = 30;

}

}

public void setName(String name) {

this.name = name;

}

/* 获取到属性的值,提供 getter 方法 */

public int getAge() {

return age;

}

public String getName() {

return name;

}

/* 测试入口 */

public static void main(String[] args) {

Person person = new Person();

person.setAge(20);

person.setName("小明");

System.out.println("name: " + person.getName());

System.out.println("age: " + person.getAge());

}

}

程序的运行结果为:

name: 小明

age: 30

在上述代码中,我们可以看出对属性进行封装后,外部代码无法直接访问这些属性。通过提供 getter() 和 setter() 方法,外部代码可以获取和设置这些属性的值,同时在 setter() 方法中可以添加验证逻辑,确保这些属性的值符合要求。

被私有化的方法可以访问,但只能在本类中调用,在其他类中无法调用。

Java 封装的好处有以下几点:

提高代码的安全性:通过限制对属性的直接访问,可以防止外部代码意外修改或破坏类的内部状态;

提高代码的可维护性:封装隐藏了类的内部实现细节,使外部代码只需关注类提供的公共接口;

内部的实现方式:如果需要修改类的内部实现方式,那么只需修改类的内部代码,而不会影响外部代码的使用;

提高代码的可扩展性:可以在不影响外部代码的情况下,向类中添加新的属性和方法,或者修改现有属性和方法的实现。

相关数据