- 👑专栏内容:Java
- ⛪个人主页:子夜的星的主页
- 💕座右铭:前路未远,步履不停
目录
- 一、封装的概念
- 二、访问修饰限定符
- 三、包
- 1、包的概念
- 2、导入包中的类
- 3、常见的包
嗨!前面我们简单的认识了一下什么是面向对象,以及类和对象的关系。
想象一下,假设我们的类就是一个房间,房间里面布置着各种装饰,这些装饰就好比是类中的方法,只能被房间的居住者使用。如果我们的房间没有四面墙来保护,那么房间内的一切都会暴露给外界。有了墙的保护,房间内的布局和装饰可以随意改变,而不会对外部产生影响。然而,如果只有墙而没有门窗,这个房子就失去了与外界互动的可能性,毫无价值。在Java中,这就是面向对象编程的三大特性之一——“封装”。让我们一同深入学习这个重要的概念。
一、封装的概念
面向对象程序三大特性:封装、继承、多态。
而类和对象阶段,主要研究的就是封装特性。何为封装呢?
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。再简单点来说就是套壳屏蔽细节。
如果上面的例子,你没有看明白,那我就再举一个生活中的例子。相信大家都会玩电脑,那么又有多少人知道一台电脑是如何做出来的呢?
对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB 插孔等,让用户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU、显卡、内存等一些硬件元件。
对于电脑的使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此电脑厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。
二、访问修饰限定符
那如何进行封装呢?
在Java中,封装是通过访问控制符(public
、private
、protected
)来实现的。
通常情况下,类的属性都应该使用private
修饰符来限制外部访问,而方法则可以使用public
修饰符来允许外部访问,从而实现对内部状态的保护和控制。
Java提供了四种主要的访问修饰符,分别是:
-
Public(公共):
- 修饰符:
public
- 表示成员对于所有类都是可见的。一个类的
public
成员可以被其他类访问。
- 修饰符:
-
Private(私有):
- 修饰符:
private
- 表示成员只能在定义它的类中访问。其他类无法直接访问这个类的
private
成员。
- 修饰符:
-
Protected(受保护):
- 修饰符:
protected
- 表示成员对于定义它的类及其子类是可见的。即使这个类在不同的包中,只要是它的子类就可以访问。
- 修饰符:
-
Default(默认,无修饰符):
- 默认情况下,没有修饰符的成员称为“包私有”或“默认访问级别”。
- 表示成员只能在同一包内的其他类中访问。在不同包中的类无法访问。
梳理成表格就是如下:
修饰符 | 类内部 | 同一包 | 子类 | 外部包 |
---|---|---|---|---|
public | ✔ | ✔ | ✔ | ✔ |
private | ✔ | ✘ | ✘ | ✘ |
protected | ✔ | ✔ | ✔ | ✘ |
默认(无修饰) | ✔ | ✔ | ✘ | ✘ |
- “✔” 表示有权访问。“✘” 表示无权访问。
【说明】
-
protected
主要是在继承中使用 -
默认
权限指:什么都不写时的权限 -
访问权限除了可以限定类中成员的可见性,也可以控制类的可见性
三、包
1、包的概念
在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
简单来说,包就像是一个文件夹,里面存放着相关的Java类。这样,当项目变得庞大时,你可以更轻松地管理和组织你的代码,防止不同类之间的名字发生冲突,使得整个项目结构更加清晰。
2、导入包中的类
Java 中已经提供了很多现成的类供我们使用.
例如Date类:可以使用 java.util.Date
导入 java.util
这个包中的 Date类
public class Test {public static void main(String[] args) {java.util.Date date = new java.util.Date();// 得到一个毫秒级别的时间戳System.out.println(date.getTime());}
}
但是这种写法比较麻烦一些, 可以使用 import语句导入包
import java.util.Date;
public class Test {public static void main(String[] args) {Date date = new Date();// 得到一个毫秒级别的时间戳System.out.println(date.getTime());}
}
如果需要使用 java.util
中的其他类, 可以使用 import java.util.*
import java.util.*; // .*相当于一个通配符,可以充当任何类
public class Test {public static void main(String[] args) {Date date = new Date();// 得到一个毫秒级别的时间戳System.out.println(date.getTime());}
}
但是更建议显式的指定要导入的类名,否则还是容易出现冲突的情况
import java.util.*;
import java.sql.*;
public class Test {public static void main(String[] args) {// util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错Date date = new Date();System.out.println(date.getTime());}}
// 编译出错
Error:(5, 9) java: 对Date的引用不明确
java.sql 中的类 java.sql.Date 和 java.util 中的类 java.util.Date 都匹配
在上面这种情况下,则需要使用完整的类名
import java.util.*;
import java.sql.*;
public class Test {public static void main(String[] args) {java.util.Date date = new java.util.Date();System.out.println(date.getTime());}
}
可以使用import static导入包中静态的方法和字段。
import static java.lang.Math.*;
public class Test {public static void main(String[] args) {double x = 30;double y = 40;// 静态导入的方式写起来更方便一些.// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));double result = sqrt(pow(x, 2) + pow(y, 2));System.out.println(result);}
}
注意事项:
-
import
和 C++ 的#include
差别很大, C++ 必须#include
来引入其他文件内容, 但是 Java 不需要 -
import
只是为了写代码的时候更方便,import
更类似于 C++ 的namespace
和using
3、常见的包
-
java.lang
:系统常用基础类(String、Object),此包从JDK1.1后自动导入。 -
java.lang.reflflect
:java 反射编程包; -
java.net
:进行网络编程开发包。 -
java.sql
:进行数据库开发的支持包。 -
java.util
:是java提供的工具程序包。(集合类等) 非常重要 -
java.io
:I/O编程开发包。
今天封装就先说到这里了,下一篇我们继续学习面向对象的其他特性。下次再见哦~