包的定义
在实际项目开发过程中,所有的类必须放在包里面。多人合作的项目开发,可能产生类的重名问题。在操作系统中严格规定:==同一个目录下不允许存放有相同程序类文件。==但是实际过程中往往不能保证完全不重复,为了方便类的管理,往往将程序文件放在不同的目录下,不同目录下可以提供相同文件。包的本质时目录。
package cn.mldn.demo;//定义包,其中.表示分割子目录
public class Bao {
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
一旦程序开发过程中出现包,此时编译以后的结果就必须将*.class保存在该包指定目录中,此时手工建立将会很麻烦。最好的做法是进行打包编译处理:
javac -d . Bao.java
·“-d”:表示要生成目录,而目录结构就是package定义目录;
·“.”:表示在当前所在目录生成程序类文件;
在程序执行过程中,必须带入包一起:java cn.mldn.demo.Bao
完整的类名称:包名.类名
DOS执行以上程序如下:
包的导入
利用包可以将不同功能的类保存在不同的包中,但是有时候这些类之间存在互相调用关系,这个时候使用import语句导入其他程序类。
例子:定义一个程序类“cn.mldn.util.Message”,这个负责进行一个数据消息获取。
package cn.mldn.util;//定义包
public class Message{
public String get(){
return "wolaizigansutianshui";
}
}
例子:定义一个测试类,使用Message类——cn.mldn.test.Test
package cn.mldn.test;
import cn.mldn.util.Message;//导入其他包的类
public class Test {
public static void main(String[] args)
{
Message a=new Message();
System.out.println(a.get());
}
}
输出结果:wolaizigansutianshui
通过测试类调用程序类,得到输出结果。按照正常逻辑,在编译过程中应该先编译程序类,后编译测试类。但是如果导入包数量过于庞大,编译起来极为麻烦。此时可以通过Java自己编译来完成:javac -d . *.java;
注意:关于public class与class定义类的区别?
·public class:类名称与文件名必须保持一致,一个*.Java文件里面只允许有一个public class类。若果一个类需要被其他类引用,则该类只能定义为public class。
·class:类名称与文件名可以不一致,一个*.Java文件里面允许有多个class类,编译后形成不同的*.class文件。class定义的类只能被本包所访问,不能被其他类导入引用。
·在实际开发之中往往在一个*.java源代码文件里面只会提供一个程序类。所有程序包名称全部小写。
有时候会使用一个包中的许多类,但是一个一个导入比较麻烦,这个时候就需要使用通配符“*”来处理:
import cn.mldn.util.*;
导入其他包的类。此时并非全部加载全部类,而是根据所需自动提取所取的类程序 。
但是如果开发之中采用“包.*”形式导入时,会产生一个问题:有可能两个不同的包中存在相同的类名称。
例子:存在两个类名都为Message的类
package b1;
public class Message{
public String get(){
return "wolaizigansutianshui";
}
}
***************************
package b2;
public class Message{
public String get(){
return "lanzhouligongdaxue";
}
}
***************************
package bao;
import b1.*;
import b2.*;
public class Bao {
public static void main(String args[]) {
Message a=new Message();
System.out.println(a.get());
}
}
运行程序出现以下错误:
Exception in thread “main” java.lang.Error: Unresolved compilation problems:
The type Message is ambiguous
The type Message is ambiguous
at bao.Bao.main(Bao.java:6)
修改如下:
package bao;
import b1.*;
import b2.*;
public class Bao {
public static void main(String args[]) {
b1.Message a=new b1.Message(); //实例化对象时候前面应该说明具包名.类名
System.out.println(a.get());
}
}
静态导入
假如有一个类,这个类的全部方法都是static方法,那么按照原始做法要导入所在的包.类,而后才通过类名称调用这些静态方法。
例子:定义一个MyMath数学类
//数学类
package a.a.a; //定义包
public class MyMath{
public static int add(int...args){
int m=0;
for(int x: args){
m+=x;
}
return m;
}
public static int sub(int p,int q){
return p-q;
}
}
1.旧的处理方法
导入形式为 import 包名.*;
在使用被导入的静态方法的时候该方法通过“类名.方法”使用。
//主类
package a.a.b; //定义包
import a.a.a.*; //导入其他包的类
public class Test {
public static void main(String[] args)
{
System.out.println(MyMath.add(10,20,30)); //通过类名调用方法使用
System.out.println(MyMath.sub(20,30));
}
}
2.静态导入
导入形式为 import static 包名.类名.*;
在使用被导入的静态方法的时候该方法可以看作本类方法直接使用。
package a.a.b;
import static a.a.a.MyMath.*;//导入其他包的类
public class Test {
public static void main(String[] args)
{
System.out.println(add(10,20,30));
System.out.println(sub(20,30));
}
}
静态导入以后就好比方法是写在类中的,可以由主方法直接掉用。减少了重复类。
注意:class定义的类只能被本包所访问,不能被其他类导入引用。。
生成jar文件
当一个项目开发完成会存在大量的*.class文件,这些文件往往以压缩结构形式来处理,这样的结构称为jar文件。如果想要将程序打包为jar,可以直接利用jdk命令来实现。实现步骤如下:
第一:定义一个简单文件
package c.c.c;
public class MyMath{
public static int add(int...args){
int m=0;
for(int x: args){
m+=x;
}
return m;
}
public static int sub(int p,int q){
return p-q;
}
}
第二:程序进行编译与打包处理
·对程序打包编译:javac -d . MyMath.java
·此时形成包,包里面含有子包与*.class文件,将其打包为my.jar。
输入指令:jar -cvf my.jar x
——“-c”:创建一个新的jar文件;
——“-v”:得到一个详细输出;
——“-f”:设置jar文件名称(此处为my.jar)
——“x”:表示打包成jar以后的存放位置。
——“my.jar”:表示打包以后的文件名
第三:每一个jar文件都是一个独立的程序路径,如果想要在java中使用此路径,必须通过classpath配置。
SET CLASSPATH=.;F:\Java学习\bao\my.jar
第四:建立测试类,导入MyMath类并且测试方法
package a.a.a;
public class Test {
public static void main(String[] args)
{
System.out.println(add(10,20,30));
System.out.println(sub(20,30));
}
}
·编译程序:javac -d . Test.java
·解释程序:java a.a.b.Test
如果此时编译程序之后classpath发生了改变,类无法加载。
系统常用包
JDK中提供大量的类库,并且这些类库都是封装在不同的Java开发包中的:
1·java.lang:String,Number,Object等都在这个包里面,jdk1.1开始自动加载;
2·java.lang.reflect:反射机制处理包,所有设计从此开始;
3·java.util:工具类的定义,包括数据结构定义;
4·java.io:进行输入与输出流操作程序包;
5·java.net:网络程序开发程序包;
6·java.sql:进行数据库编程的开发包;
7·java.applet:Java的原始使用形式,直接嵌套在网页上执行的程序开发包;
——现在程序开发以Application为主(有主方法的程序)
8·java.awt、javax.swing:Java图形界面开发包(GUI),其中awt是属于重量级的组件,swing是轻量级的组件;
访问控制权限
在面向对象开发过程中有三大特点:封装、继承、多态。
访问控制权限4种,使用约束范围如下:
在整个访问权限控制中,只有protected(受保护)为最新概念,下面举例描述。
定义两个类:·a.a.a.A类,提供protected访问权限;·a.a.b.B类:将直接访问protected属性:
例子:通过子类访问父类protected属性
父类
package a.a.a;
public class A{
protected String info="爱我中华";
}
子类
package a.a.b;
import a.a.a.A;
public class B extends A{ 继承父类
public void print(){
System.out.println(super.info); //super调用父类属性
}
}
测试类1.通过子类访问protected属性
package a.a.c;
import a.a.b.*;//导入其他包的类
public class Test {
public static void main(String[] args) {
new B().print(); //子类匿名对象
}
}
输出:爱我中华
测试类2.直接访问protected属性
package a.a.c;
import a.a.a.*;//导入其他包的类
public class Test {
public static void main(String[] args) {
System.out.println(new A().info);//父类匿名对象直接访问父类属性
}
}
出现错误提示信息
使用原则:
定义属性,全部private
定义方法。全部public。
虽然无法直接进行访问,但是可以通过定义方法,如setter、getter方法进行访问。