day10_java中的包
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: (出自Java就业培训教程)
对于默认访问控制成员,可以被这个包中的其他类访问,如果一个子类与父类位于不同的包中,子类也不能访问父类中的默认访问控制成员.
protected:
如果一个成员方法或成员变量名前使用了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