欢迎来到【开开心心学java,快快乐乐写代码】此专栏,本篇博客呢将会为大家仔细讲解关于面向对象的三大特性之一:封装,以及包的知识。本来我是打算将封装、继承、多态全部在本篇博客中完成的,但是呢,我写完之后发现文章太长了,如果发出来给你们看的话会太长,这样也不太利于阅读,于是就把它分成了3篇博客,本篇博客看完之后,有想了解其他两大特性的友友们呢,可以在我的主页里面去找,每一特性都做了详细介绍。好啦,废话不多说啦,让我们进入本篇博客正题----封装,光看这两个字是不是就很抽象很模糊呢,不要担心,本博主依旧还是会讲的很仔细哒,认真看完,肯定会有所收获滴~
目录
1 、封装的概念
封装:就是将数据和操数据作的方法进行有机结合,隐藏对象的属性和方法的实现细节,仅向外提供接口来与对象来完成交互。
通俗一点来说,就是套壳隐藏细节。举个很简单的例子来理解,就是我们平常所用的电脑设备,它向外提供的就是只有开关机、键盘输入、USB接口、显示器等等,用这些向外公开的接口来完成计算机和用户的交互。但是真正工作的是计算机内部的CPU、显卡、内存等。
对于计算机使用者而言,并不需要关心CPU、内存、显卡的功能是什么、也不需要他们是怎样实现我们使用者的需求的,用户只需要知道,怎么开机、关机、怎么通过键盘输入与鼠标与计算机进行交互等。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开、关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。
2 、访问限定符
在讲封装是怎么实现之前呢,先必须要说一下这个访问限定符,了解这个之后才能更好的将封装思想运用到程序之中。
在java中,主要通过类和访问权限来实现封装:类可以很好的将数据和封装数据的方法结合起来,而访问权限直接规定了类中字段和方法能否在其他类中使用。下面是java中的四种访问修饰限定符:
注意:什么都不写时为默认权限(default)。
package test;
public class Computer {
private String cpu; // cpu
private String memory; // 内存
public String screen; // 屏幕
String brand; // 品牌---->default属性
public Computer(String cpu, String memory, String screen, String brand) {
this.cpu = cpu;
this.memory = memory;
this.screen = screen;
this.brand = brand;
}
public void fun1(){
System.out.println("-------开机------");
}
public void fun2(){
System.out.println("-------关机------");
}
}
测试如下:
package test;
public class Test{
public static void main(String[] args) {
Computer p = new Computer("i7", "8G", "13*14", "HW");
System.out.println(p.brand); // default属性:只能被本包中类访问
System.out.println(p.screen); // public属性: 可以任何其他类访问
// System.out.println(p.cpu); // private属性:只能在Computer类中访问,在Test类中不能被访问,如果不屏蔽此语句,将会报错。
p.fun1();
p.fun2();
}
}
运行结果:
注意:一般情况下,成员变量设置为private,成员方法设置为public。
3 、封装的应用举例
上述举例只是为了让大家更好的理解访问限定符的作用,接下来就是一个实现封装的简单小例子:
public class Computer2 {
private String cpu; // cpu
private String memory; // 内存
private String screen; // 屏幕
private String brand; // 品牌
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getScreen() {
return screen;
}
public void setScreen(String screen) {
this.screen = screen;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
在此代码中,我们不难发现Computer类中的属性如cpu、memory、screen,brand都是用private来修饰的。这样设计的目的就是希望除了该类的设计者能对其进行修改和查看之外,类的使用者不能直接随意对其属性进行修改或查看,如果要修改或查看,只能通过类的设计者提供的对外公开接口来进行修改或查看。在上述代码中,像这样的接口(也就是方法)就是getCpu( )、setCpu( )等,这些get和set方法可以直接通过IDEA的快捷键生成。
4 、封装拓展之包
4.1 包的概念
在面向对象体系中,引入了一个包的概念,即:为了更好的管理类,可以把多个类收集成一组放入一个文件夹中,称为软件包。比如:为了更好的管理电脑中的视频文件,我们可以对这些视频进行如下分类:
在java中,包是对类、接口等的很好的封装机制的体现,是一种对类或者接口等的很好的组织方式。比如:一个包中的类不想被其他包中的类使用等。包还有一个特点:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可,但是同一个包中不能有两个类的类名相同,就像一个文件夹中不能有两个相同名称的文件一样。
4.2 导入包中的类
Java中已经提供了很多类给我们使用,如Data类。如果我们要使用Date类,那就要用java.util.Data来导入java.util这个包中的Data类,如下:
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.*;来导入java.util这个包中所有的类。
但是我们更建议显式的指定要导入的类名. 否则容易出现冲突的情况,比如:
import java.util.*;
import java.sql.*;
public class Test1 {
public static void main(String[] args) {
// util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
Date date = new Date();
System.out.println(date.getTime());
}
}
运行结果:
编译错误,因为在 util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义,编译器不知道究竟要用哪个包里面的Data类,正如报错原因中所说,引用不明确。
4.3 自定义包
基本规则:
- 包名需尽量指定为唯一的名字,通常会用公司域名的颠倒形式,比如百度公司为www.baidu.com,则定义包时一般用com.baidu.www来命名。
- 包名与代码路径相匹配,比如创建了一个com.test.demo1的包,则会存在一个对应的路径来存储代码(com/test/demo1)。
- 如果一个类没有package语句,则该类放在一个默认包中。
4.5 常见的包
java.lang:系统常用基础类(String、Object)包,此包从JDK1.1后自动导入。
java.lang.reflect:java 反射编程包;
java.net:进行网络编程开发包。
java.sql:进行数据库开发的支持包。
java.util:是java提供的工具程序包。(集合类等) 非常重要
java.io:I/O编程开发包。
以上就是我要今天分享的内容啦,后续我还会继续更新的哒,常看我的博客会学到很多知识哦