java中的包概述:
/*
package 也就相当于windows中的文件夹
只不过存放的为类文件
当windows中有同名文件时,我们可以
放在不同的文件夹下进行存储
包同理.
包的作用:1.对 类文件 进行 分类管理
2.给类提供多层命名空间
例如:A文件夹下有Demo.class
B下也有Demo.class
我要用的是B文件夹下的Demo.class
过去之所以没有写包名->使用的java默认包机制,没有指定包->JVM把当前目录作为默认包存在
*/
package pack;//定义包名
class PackageDemo
{
public static void main(String[] args)
{
System.out.println("pack.PackageDemo");
}
}
/*
①
通过javac -d c:\myclass PackageDemo.java
-d-->指定目录(direction)(指定包及其中的类文件存放位置)
.代表当前目录
//如果不使用-d指定目录,在编译完后,必须手动创建pack文件夹,把类放入里面//才能运行,这是因为在编译过程中并不会创建pack目录.
-->执行完,会在当前目录下创建一个pack目录->里面存放PackageDemo.class
②
javac -d c:\myclass PackageDemo.java
此时如果在运行时,没有配置classpath的话,运行时找不到该类
-->set classpath=c:\myclass
为什么不写set classpath=c:\myclass\pack???
pack和PackageDemo.class是一个整体
当使用包中的一个类时,指向包的父目录(c:\myclass)即可
③
在运行时:java pack.PackageDemo //加上包名
*/
/*
包的好处:
使java源文件与类文件分离
*/
包与包之间互访的错误分析:
PackageDemo2.java
package pack;//定义包名
//当PackageDemo.class用到DemoA.class
//注意编译错误
class PackageDemo2
{
public static void main(String[] args)
{
//DemoA d=new DemoA();//错误1
//修正为
packa.DemoA d=new packa.DemoA();
d.show();
}
}
/*
PackageDemo.java:23: 错误: 找不到符号
DemoA d=new DemoA();
^
符号: 类 DemoA
位置: 类 PackageDemo
PackageDemo.java:23: 错误: 找不到符号
DemoA d=new DemoA();
^
符号: 类 DemoA
位置: 类 PackageDemo
2 个错误
原因:类名写错
因为类名全名是:包名.类名
------------------------------------
PackageDemo2.java:14: 错误: 程序包packa不存在
packa.DemoA d=new packa.DemoA();
^
PackageDemo2.java:14: 错误: 程序包packa不存在
packa.DemoA d=new packa.DemoA();
^
2 个错误
原因:packa包不在当前目录下
需要设置classpath,告诉jvm去哪里找指定的packa包.
-------------------------------------------------
PackageDemo2.java:15: 错误: DemoA在packa中不是公共的; 无法从外部程序包中对其进行
访问
packa.DemoA d=new packa.DemoA();
^
PackageDemo2.java:15: 错误: DemoA在packa中不是公共的; 无法从外部程序包中对其进行
访问
packa.DemoA d=new packa.DemoA();
^
2 个错误
错误原因:有了包,范围变大,一个包中的类要被访问必须要有足够大的权限
-->类只有两个权限:一个默认一个public
----------------------------------------
PackageDemo2.java:16: 错误: show()在DemoA中不是公共的; 无法从外部程序包中对其进
行访问
d.show();
^
1 个错误
错误原因:类公有后,被访问的成员也要公有才可以访问.
*/
/*
总结:
1.包与包之间之间进行访问,被访问的包中的类以及类中的成员,需要公有
包也是一种封装形式
假设包中有10个类,只有一个public了
那么9个在内部使用,只有一个提供出去
通俗点说:
你不能进入我家,玩不了ipad
你可以进入我家,但我把ipad藏起来了
你也玩不了
*/
DemoA.java
package packa;
public class DemoA
{
public void show()
{
System.out.println("show()");
}
}
当一个包中类继承另一个包中的类:
DemoB.java
package packb;
public class DemoB
{
protected void method()
{
System.out.println("DemoB");
}
}
/*
//当method()修饰符为public时,以上可以运行成功,引发一个问题
DemoA extends DemoB
可以使用method();
而PackageDemo也可以直接使用DemoB
通俗的说:
->DemoA当了DemoB的儿了,拿到DemoB内容
->PackageDemo不当DemoB的儿子,同样拿到了
--->
权限修饰符:protected,不是我儿子不让你拿(O(∩_∩)O哈哈~)
*/
修改下DemoA.java
package packa;
public class DemoA extends packb.DemoB
{
public void show()
{
System.out.println("show()");
method();
}
}
PackageDemo2.java保持不变.
如果在PackageDemo2.java中加入packb.DemoB d=new packb.DemoB(); d.method();
权限修饰符总结:
2.不同包中的子类还可以直接访问父类中被protected权限修饰的成员
包与包之间可以使用的权限只有两种:public,protected
权限总结:
public protected default private
同一个类中 OK OK OK OK
同一个包中类 OK OK OK NO
子类 OK OK NO/OK NO
不同包中 OK NO NO NO
以上子类default:
NO
子类和父类在不同包中,当我把DemoB中method方法的修饰符protected去掉,子类无法使用方法method.(错误提示:找不到符号,method())
OK
父类和子类在同一个包中,默认权限,子类可以使用父类方法
注意:
如果我想pack包中的PackDemo2.class 访问同一包下的DemoB.class和DemoC.class(假设在DemoB.java中)
这时候必须新建一个java文件把DemoC放入(开始代码package packb;)
default:
对于默认访问控制成员,可以被这个包中的其他类访问,如果一个子类与父类位于不同的包中,子类也不能访问父类中的默认访问控制成员.
protected:
那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问
在子类包中只能通过子类对象方式调用protected修饰的方法(在复写时,经过测试,不能通过多态方式调用Father f=new Son() ,f.method() 会报Father中的方法不可见)
public:
如果一个成员方法或成员变量名前使用了public,那么这个成员即可以被所有的类访问,不管访问类与被访问类是否在同一个包中
import关键字:
package pack;
/*
为了简化类名的书写,使用一个关键字:import
import 导入的是包中的类
①建议,不要写通配符 * ,需要用到包中的哪个类,就导入哪个类.
②当导入的不同包中类出现重名时,这个类必须加包名.类(区分哪个包中的类)
③建议定义包名不要重复,可以使用url来完成定义,url是唯一的.
例如:
www.baidu.com
package com.baidu.demo
package com.baidu.test
*/
import packb.packc.packd.DemoC;
//import packb.packc.packd.*;//*把packd目录下所有的类导入
class PackageDemo3
{
public static void main(String[] args)
{
//想访问多层包目录下的DemoC时
packb.packc.packd.DemoC dc=new packb.packc.packd.DemoC();//以上显得非常繁琐-->引入import(导入),可简化为以下形式
DemoC dc2=new DemoC();
}
}
/*
c:\myclass下有一些类
c:\myclass\packb\DemoA.class
c:\myclass\packb\haha\DemoZ.class
import packb.* //仅仅导入的DemoA.class
//要想导入DemoZ.class
import packb.haha.DemoZ
*/
DemoC.java
package packb.packc.packd;//包里面有包(多层包目录)
//包进行逐级存放,对类进行分层管理
//编译后形成g:\myclass\packb\packc\packd\DemoC.class
public class DemoC
{
}
java中的jar.exe(打包)
package pack;
import packa.*;
//运行jar包中的类,把jar包所在路径写入classpath中
class JarDemo
{
public static void main(String[] args)
{
DemoA a=new DemoA();
a.show();
System.out.println("JarDemo Over");
}
}
/*
运行环境所用到的类都在jre\lib\rt.jar中
编译环境所用到的类都在jdk\lib\tools.jar中
src.zip:java所有类的源文件(.java)(以前犯得一个命名错误)
为什么JDK里面要含有一个jre?
编译工具使用类写的->这些类需要JVM运行->必须含有jre
*/
DemoA.java
package packa;
public class DemoA
{
public void show()
{
System.out.println("show()");
}
}
注意以下命令:
将G:\myclass下的pack和packa包下的类进行压缩归档到heixiu.jar中.
要压缩的.jar或.class均可指定目录不一定是当前目录.
要想在任意目录运行.jar文件中的内容 set classpath=g:\myclass\heixiu.jar