JavaSE 7th day
—— Package &Access Permissions
1、本次课程知识点
1、包的定义及导入;
2、系统常见包的作用;
3、四种访问控制权限。
2、具体内容
2.1 包的作用(重点)
在实际的开发之中,都是多人进行同一个项目的开发工作,但是如果按照之前的方法开发,则会存在一个问题:不同的开发者可能起同样的类名称,这样一来就会发生覆盖的问题,因为在同一个文件夹之中,不能存在同名文件,但是在不同的文件夹之中,却可以存在同名文件,所谓的包就是指一个文件夹而已。
2.1.1 包的定义
如果现在希望在程序中将一个类保存在包之中,则可以使用package关键字完成。
package org.demo; //定义包,每一个.用于区别分子文件夹
public class Hello{ public static void main(String args[]) { System.out.println("Hello World."); } } |
此时,如果在编文件的时候,必须建立好文件夹,那么编译的命令如下:
java -d . Hello.java:此时会自动根据package的定义生成文件夹,参数的作用如下:
● “-d”:表示生成文件夹,根据package的定义生成;
● “.”:表示在当前所在的文件夹中生成内容;
一旦程序有包之后,那么一个最明显的问题就出现了,一个类的完整名称就变成了“包.类”,执行:
java org.demo.Hello |
即:使用包之后,可以将类保存在文件目录之中,方便功能管理,而且在开发之中,没有包是绝对不存在的。
2.1.2 包的导入
既然现在要求程序都要分包保存,那么这之间就有可能出现不同包的类互相访问的情况,此时就必须使用import语句执行导包操作。
范例:定义一个工具类—— Tools.java
package org.lxh.util;
class Tools{ public String getInfo(){ return "Hello World"; } } |
范例:定义一个Test.java类,用于导入以上的包
package org.Ixh.test; import org.Ixh.util.Tools;
public class TestJava{ public static void mian(Stirng args[]){ System.out.println(new Tools().getInfo()); } } |
现在程序编写完成之后,应该进行编译的操作,很明显应该先编译Tools.java之后在编译TestJava.java,因为后者要引用前者的操作:
● 编译Tools.java:javac -d . Tools.java;
● 编译TestJava.java:javac -d . TestJava.java,此时出现了如下的错误信息:
现在的错误信息:Tools不是一个public声明的,不能被外包所访问。
总结:public class和class的区别?
● publicclass:文件名称必须和类名称保持一致,在一个*.java文件之中只能定义一个publicclass。如果一个类希望被外包所访问,声明为publicclass;
● class:文件名称可以和类名称不一致,但是执行的时候要执行类名称,在一个*.java文件之中可以定义多个class,但是只能有一个public class,而且不同的定义含义分别生成不同的*.class文件。如果一个类只希望被本包所访问,声明为class;
范例:修改Tools.java的定义
package org.lxh.util; public class Tools{ public String getInfo(){ return "Hello World"; } } |
此时修改完成之后很明显还是要想之前那样按照先后顺序进行编译,但是太麻烦了,所以现在有一种更为简单的编译方法:java-d . *.java;
通过这一程序可以发现,要想导入其他类必须连同包名称一起导入“org.Ixh.util.Tools”,但是如果说现在的程序要同时导入org.Ixh.util中的多个类,则采用上面的编写肯定很麻烦,所以可以使用通配符“*”来表示。
package org.Ixh.test; import org.Ixh.util.*;
public class Test{ public static void mian(Stirng args[]){ System.out.println(new Tools().getInfo()); } } |
此时的效果是一样的,而且使用“*”与分别的单独导入性能是一样的,因为即使使用“*”也表示只加载所需要的类,不需要的类不再加载。
既然现在存在了导包的操作,那么就可能出现一个项目中同时导入不同包的相同类的情况。
范例:现在再定义一个Tools.java类
package cn.mldn.demo; public class Tools{ public String getInfo(){ return "中国,你好!"; } } |
下面会根据某种要求,TestJava类中同时要导入这两个包。
package org.Ixh.test; import org.lxh.util.*; import cn.mldn.demo.*;
public class TestJava{ public static void main(String args[]){ System.out.println(new Tools().getInfo()); } } |
那么这种情况下,编译TestJava类会出现如下的错误提示:
错误信息:“引入的Tools类不明确,两个类cn.mldn.demo.Tools和org.lxh.util.Tools都匹配”,所以在这种情况下,为了解决此类的矛盾,最好在使用类的时候明确的加上完整的“包.类”名称。
package org.Ixh.test; import org.lxh.util.*; import cn.mldn.demo.*;
public class TestJava{ public static void main(String args[]){ org.lxh.util.Tools t1 = new org.lxh.util.Tools(); System.out.println(t1.getInfo()); cn.mldn.demo.Tools t2 = new cn.mldn.demo.Tools(); System.out.println(t2.getInfo()); } } |
Hello World. 中国,你好! |
以后这种同名不同包的类会经常被导入进来,所以以上的语法必须清楚,而且记住,类的完整名称中本身就有包的名称,即:包.类名称。
2.1.3 jar命令
当一个项目开发完成之后,肯定要交付给用户使用,但是一个项目之中会存在大量的*.class文件,这样对于项目的理解并不方便,所以此时,可以将这些*.class文件打成一个jar包的形式方便管理。
在JDK之中已经为用户默认提供了jar操作命令,直接输入即可。
在这之中,主要使用jar命令中的三个参数:
● -c:创建新的文件;
● -v:输出完整的压缩信息;
● -f:指定文件的名称。
范例:现在定义一个:cn.mldn..util.Hello
package cn.mldn.util; public class Hello{ public String getInfo(){ return "Hello World."; } } |
下面按照如下的步骤将以上的代码编译后打包;
● 第一步,打包编译:javac-d . Hello.java;
● 第二步,打包Jar:jar -cvf my.jar cn;
范例:定义类,使用my.jar包中Hello.class
package org.Ixh.test; import cn.mldn.util.*;
public class TestJava{ public static void main(String args[]){ System.out.println(new Hello().getInfo()); } } |
此时my.java和TestJava.java文件保存在同一文件目录之中,下面编译TestJava.java程序。
javac -d . TestJava.java |
但是,此时会提示错误信息:找不到包的错误。
对于jar文件而言,本身是一个压缩文件,所以对于程序而言,这个压缩文件就相当于是一个新的目录,即:如果要想访问其他目录(压缩文件)的话就必须配置CLASSPATH属性。
SET classpath=.;d:\javatest\my.jar |
而后重新编译之后就可以成功了,所以所有的jar文件必须配置classpath,而上面的这种classpath只针对一个命令行起作用,如果要想针对整个系统起作用,则可以在环境属性中进行配置(可以用“;”添加多个变量值)。
3.2 系统的常见包(了解)
Java平台之所以现在发展比较快,主要的原因也在于各个公司和组织的支持,而在JDK之中为了方便开发,也提供了大量的系统包,有如下几个包:
● java.lang:里面包含了像Object、String、Integer等类,这个包在JDK1.1之后自动导入;
● java.lang.reflect:进行反射机制的操作包;
● java.util:工具包,这个包是一个核心包;
● java.io:进行输入/输出操作的;
● java.sql:进行数据库操作包;
● java.net:网络编程的开发包;
● java.applet:是作为Applet开发使用的;
● java.awt、javax.swing:图形界面使用的(JFC开发包);
Applet程序是java最早出现的形式,而现在已经随着技术的发展,Applet不再使用了,而之前所讲解的程序都属于Application程序,即是用主方法运行的,而Applet是在Applet是在网页上运行的,但是后来由于SUN和微软的战争,导致此技术完蛋了,也是导致了图形界面的死亡。
图形界面的开发使用两种包:
● java.awt:是一种轻量级的操作组件,使用了大量的Windows函数;
● javax.swing:是一个扩展表,表示轻量级的图形组件,使用java开发,在JDK1.2时推出,也成为了JDK1.2的一个著名标志,之后java就变成了java 2;
2.3 命名规范(重点)
在任何的项目开发之中,都需要按照组织规定号的方法进行命名编写,但是在java之中也有一些属于自己的命名规范:
1) 类名称:每个单词的首字母大写,例如:TestJavaDemo;
2) 方法名称:第一个单词的首字母小写,之后每个单词的首字母大写,例如:printInfo( );
3) 属性名称:第一个单词的首字母小写,之后每个单词的首字母大写,例如:studentName;
4) 常量名称:所有单词的字母大写,例如:INFO;
5) 包名称:所有单词的字母小写,例如:org.lxh.demo;
这些只是一些基本的规范,而在各个公司有各个公司自己的规范,必须遵守。
2.4 访问权限(重点)
在java中有四种访问控制权限,分别如下:
No | 范围 | private | default | protected | public |
1 | 同一类 | √ | √ | √ | √ |
2 | 同一包中的类 |
| √ | √ | √ |
3 | 不同包的子类 |
|
| √ | √ |
4 | 其他包中的类 |
|
|
| √ |
在之前已经学习过了private、default、public、下面主要观察一下protected权限。
范例:定义一个A类:org.lxh.testa.A
package org.lxh.testa;
public class A{ protected String mdg = "Hello"; //只能被本包或不同包的子类访问 } |
范例:定义一个B类,此类继承A类
package org.lxh.testb; import org.lxh.testa.*;
public class B extends A{ public void print(){ System.out.println(super.mdg); //不同包子类访问保护属性 } } |
范例:定义测试类,使用B类
package org.lxh.test; import org.lxh.testb.*;
public class TestJava{ public static void main(String args[]){ new B().print(); } } |
Hello |
范例:将测试类修改
package org.lxh.test; import org.lxh.testa.*;
public class TestJava{ public static void main(String args[]){ A a = new A(); System.out.println(a.mdg);//错误!不同包的类无法访问protected属性 } } |
D:\javatest>javac -d . *.java TestJava.java:7: 错误: mdg可以在A中访问protected System.out.println(a.mdg); ^ 1 个错误 |
此时在进行编译的时候将出现错误的提示信息。
而对于四种访问权限,常用情况下的使用原则;
● private:主要用于定义属性,而且某些内部类上如果不希望被外部看见也可以使用private;
● public:定义类、接口、方法的时候都使用它;
● protected:一般在系统类中比较常用,个人的开发见的比较少一些。
3、总结
1、所有的程序都必须保存在包之中;
2、四种权限的作用及特点,封装性指的就是访问控制权限。