在实际开发过程之中,肯定要一直存在有包的概念,利用我们的包可以实现类的包装,在以后的实际开发之中,所有的类都必须放在包里面
包的定义与使用
- 同一个目录之中不允许存放有相同的程序类文件,为了可以进行类的方便管理,那么往往可以把程序文件放在不同的目录下,而这个目录就可以称为包,包 = 目录;
//定义包
package hello.test; //定义包,其中.表示分割子目录(子包)
public class Hello {
public static void main(String [] args) {
System.out.println("Hello world");
}
}
- 一旦程序之中出现有包,此时程序编译后的结果就必须将*.class的文件保存在指定目录之中,但是如果手工建立则非常麻烦,那么此时最好的做法是可以进行打包编译处理:javac -d . Hello.java
- “-d”:表示要生成目录,而目录的结构就是package定义的结构;
- “.”: 表示在当前所在的目录中生成程序类文件;
- 在程序执行的时候一定要带着包执行程序类:java hello.test.Hello,也就是说从此以后完整的类名称是“包.类”名称;
包的导入
- 利用包的定义实际上就可以将不同的功能的类保存在不同的包之中,但是这些类彼此之间也一定会存在有互相调用的关系,那么这个时候就需要使用import语句来导入其他包之中的程序类;
//定义一个程序类 “util”,这个类负责进行一个消息数据的获取
//Message.java
package util;
public class Message {
public static void main(String [] args) {
}
public String getContent() {
return "这是一个消息";
}
}
//TestMessage.java
package test;
import util.Message;
public class TestMessage {
public static void main(String [] args) {
Message msg = new Message();
System.out.println(msg.getContent());
}
}
- 此时编译出现依赖,当文件过多,相互依赖时,你并不能分辨出先编译哪个.java文件,所以此时的编译命令为:javac -d . *.java;
- 注意public class 与 class的区别:
- public class:类名称必须与文件名称保持一直,一个*.java文件里面只允许有一个public class,同时如果一个类需要被其他的包使用,那么这个类一定要定义为public class;
- class:类名称可以与文件名称不一致,并且在一个.java里面可以提供有多个class定义,编译后将形成不同的.class文件,但是这些类,只能够被本包所访问,外包无法访问
- 在实际开发之中往往一个*.java源代码文件里面只会提供一个程序类,而这个程序类一般都使用public class定义;
- 但是这个时候新的问题产生了,有些时候可能会使用某一个包中的很多类,于是这样分开进行类的导入会比较麻烦,为了解决这样一个问题,也可以使用通配符“ * ”来处理
- 即便使用了” 包.* “的导入形式,那么也不表示要进行全部的加载,它会根据自己的需要加载所需要的程序类,而不需要的程序类是不会被加载的,所以使用“ * ”还是使用具体的类其最终的性能是完全相同的;
- 但是如果我们在开发之中采用的是“ 包.* ”的形式进行包的导入时,有一点会比较麻烦:有可能会有两个不同的包中存在有相同的类名称,例如上面所写的TestMessage需要导入两个包:util、demo,但是这两个包里面都有Message类,这个时候Message msg = new Message() 就会引用不明确,所以此时最简单的处理方式就是直接写上类的完整名称;
package test;
import util.*; //导入其他包的类
import demo.*; //导入其他包的类
public class TestMessage {
public static void main(String [] args) {
util.Message msg = new util.Message();
System.out.print(msg.getContent());
}
}
包的静态导入
假如说现在有一个类,这个类中的全部方法都是static方法,按照原始的做法肯定要导入程序所在的“ 包.类 ”,然后才可以通过类名称调用这些静态方法;
//原始方式
//MyMath.java
//定义一个MyMath数学类
package util;
public class MyMath {
public static void main(String [] args) {
}
public static int add(int ...args) {
int sum = 0;
for(int temp : args) {
sum += temp;
}
return sum;
}
public static int sub(int x, int y) {
return x - y;
}
}
//TestMath.java
package test;
import util.MyMath; //导入其他包的类
public class TestMath {
public static void main(String [] args) {
System.out.println(MyMath.add(10, 20, 30));
System.out.println(MyMath.sub(30, 20));
}
}
- 从JDK1.5开始对于类中全是静态方法提供的特殊类是可以采用静态导入处理形式的;
//静态导入处理
package test;
import static util.MyMath.*; //导入其他包的类
public class TestMath {
public static void main(String [] args) {
System.out.println(add(10, 20, 30));
System.out.println(sub(30, 20));
}
}
- 当使用了静态导入处理之后就好比该方法是直接定义在主类中的,可以由主方法直接调用;
生成jar文件
- 当一个项目完成之后一定会存在有大量的*.class文件,那么对于这些文件的管理往往可以利用一种压缩结构的形式来进行处理,而这样的结构在Java之中就被成为jar文件,如果要想将程序打包为jar文件,那么可以直接利用jdk中提供的jar命令完成;
- 对程序进行编译与打包处理:
- 对程序打包编译:javac -d . Message.java
- 此时会形成util的包,包里面有对应的子包和*.class文件,将其打包为my.jar:jar -cvf my.jar util
- -c:描述的是创建一个新的jar文件;
- -v:得到一个详细输出;
- -f:设置要生成的jar文件的名称,本处是my.jar;
- 每一个*.jar文件都是一个独立的程序路径,如果想要在我们的Java程序之中使用此路径,则必须通过CLASSPATH进行配置:
- SET CLASSPATH=.;d:\my\util.jar;
- 建立测试类,直接导入Message类并且调用方法;
- JDK1.9之后出现的模块化操作:
- 在JDK1.9以前所有历史版本之中实际上提供的是一个所有类的*.jar文件(rt.jar、tools.jar),在传统的开发之中,只要启动了Java的虚拟机,那么就需要加载这两个文件;
- 在JDK1.9之后提供了一个模块化的设计,将原本很大的需要加载的一个*.jar文件变成了若干个模块文件,这样在启动的时候可以根据程序加载指定的模块(模块中有包),这样就可以启动更快;
系统常用包
- JAVA语言从发展至今一直提供有大量的支持类库,这些类库一般由两个方面组成:
- Java自身提供的(除了JDK提供的类库之外还会有一些标准);
- 由第三方厂商提供的Java支持类库,可以完成各种你所需要的功能,并且支持的厂商有很多;
- 而在JDK之中也会提供大量的类库,并且这些类库都是封装在不同的开发包之中的:
- java.lang:像String、Number、Object等类都在这个包里面,这个包在JDK1.1之后默认导入;
- java.lang.reflect:反射机制处理包;
- java.util:工具类的定义,包括数据结构的定义;
- java.io:输入与输出流操作的程序包;
- java.net:网络程序开发的程序包;
- java.sql:进行数据库编程的开发包;
- java.applet: Java的最原始的使用形式,直接嵌套在网页上执行的程序类,现在的程序已经以application为主了(有主方法的类);
- java.awt、javax.swing:Java的图形界面开发包(GUI),其中awt是属于重量级的组件,而swing是轻量级的组件;
访问控制权限
- 在面向对象开发过程之中有三大特点:封装、继承、多态。那么对于封装性而言主要的实现依靠就是访问的控制权限,而访问控制权限在程序中定义一共有四种:private、default、protected、public;
No. | 访问范围 | private | default | protected | public |
---|---|---|---|---|---|
01 | 同一包中的同一类 | ✔️ | ✔️ | ✔️ | ✔️ |
02 | 同一包中的不同类 | ✔️ | ✔️ | ✔️ | |
03 | 不同包的子类 | ✔️ | ✔️ | ||
04 | 不同包的所有类 | ✔️ |
- 在整个访问控制权限的处理之中,只有protected(受保护)的权限是比较新的概念,下面对这一访问权限的使用进行说明,定义两个类:
- util.a.Message:提供有protected访问权限;
- util.b.NetMessage:将直接访问protected属性;
//Message.java
package util.a;
public class Message {
protected String info = "www.baidu.com";
}
//NetMessage.java
package util.b;
import util.a.Message;
public class NetMessage extends Message {
public void print() {
System.out.println(super.info);
}
}
//TestMessage.java
package test;
import util.b.NetMessage;
public class TestMessage {
public static void main(String [] args) {
new NetMessage().print();
}
}
- 如果此时直接通过Message来访问info属性就会出现错误提示
//TestMessage.java
package test;
import util.a.Message;
public class TestMessage {
public static void main(String [] args) {
System.out.println(new Message().info);
}
}
- 在程序之中的封装一共有三个对应的权限:private、default、protected,但是如果每次在使用的时候进行区分会比较麻烦,所以给出一个参考的方案:
- 只要是进行属性的定义全部使用private;
- 只要是进行方法的定义全部使用public;
网友评论