这次字数又超了,发表不了,所以把后面一些剪切过来了,费了好半天劲重新调整了一下格式,呜呜~下次要长记性啦!字数过多就换一篇文章来写~
07-面向对象(包package)
什么叫包呢?
我们来思考一下~
我们会发现,在进行Java程序开发的时候,会写出很多Java文件。同时,编译之后会产生很多的类文件。
那么当类文件产生之后就会出现很多的问题。
比如,当类的内容不一样,而类的名称重复时,在一个文件夹下只能存在一个类文件。我们需要对它们用文件夹进行区分,而这个文件夹在Java中通过包表示。而Java中的包也就是文件系统中的文件夹。
所以,包:
1,对类文件进行分类管理。
2,给类提供多层命名空间。
原来呢,这个文件叫Demo.class。后来因为有两个Demo.class,所以将它们分别存了。一个Demo.class存到A文件夹中去了,一个Demo.class存到B文件夹中去了。
这个时候说,我想用一下Demo.class,那么要用的是哪一个呢?
所以这个时候就要指明,我要A的Demo.class。所以这个时候Demo.class又多了一层扩展名称 A.Demo.class。
比如,日本有秋名山,临潼也有秋名山,我们要去秋名山,那到底是哪一个呢?所以要说清楚,我们要去临潼的秋名山~
3,写在程序文件的第一行。
包名所有的字母都是小写。
4,类名的全程是 包名.类名。
举例:
编译,生成了一个class文件:
可是运行之后发现出现了类名错误:
注意,有了包名之后,类名的全称就是包名.类名辣~
改一下:
可是怎么还是错啦?
噢噢,原来是我没有pack这个文件夹呀。
所以新建一个pack文件夹:
并把PackageDemo.class移动到它的里面。
再次执行:
OK啦!
但是,如果每次都得自己新建文件夹,经过几次之后是不是都要疯啦!
源文件当中是不是已经明确了包呀?那我们让自己生成包,是不是才是最爽哒?
接下来注意看哦,我们要改一下啦。在编译的时候,如果源文件当中带着package这样的关键字定义包的话,在编译的时候就需要做一件事情,叫做:加参数。我们都知道,一个命令就是一个功能,这个命令如果加了参数,就是加了辅助功能。
编译,发现自动生成了pack文件夹:
这时再运行,OK啦:
也可以不指定当前目录,我们换一个位置:
这个位置就会新建一个pack文件夹:
我们发现,包的出现有一个好处,可以让Java的类文件(源文件)和Java的运行文件相分离。当对方想要拿我程序的时候,我只需要将运行程序拷给他就可以用啦,没必要将源文件给他。
接着上一步,我们运行:
发现挂啦,当前目录下没有这个类。
我们可以把目录切到C盘那个目录下,但也可以不那么做,有其他方法:
set classpath一下。注意,我们只要指定到包的父目录即可,后面不必跟pack,pack和PackageDemo.class是一个整体~
5,包也是一种封装形式。
08-面向对象(包与包之间访问)
不同包中的类该如何访问呢?
packa包:
pack包:
按照我们以前的写法,是这样创建DemoA的的对象并调用show方法的。
试着编译运行。
应该先编译DemoA(否则它还没有,PackageDemo怎么调用呢~):
这一步OK啦。
接着编译PackageDemo:
错误原因:类名写错。
注意,类名不是DemoA哦,类名的全名应该是packa.DemoA。(包名.全名)
改一下:
继续编译:
还是错啦,不过提示变了,说这个软件包不存在。
错误原因:packa包不在当前目录下,需要设置classpath,告诉jvm去哪里找指定的packa包。
OK~我们set classpath一下,编译,还是错了:
错误原因:有了包,范围变大,一个包中的类要被访问,必须要有足够大的权限,所以被访问的类要被public修饰。DemoA的权限不够大,需要将它设置成public。
改成public:
类的修饰符只有两种,默认或者public。
改完之后重新编译一下DemoA,然后编译PackageDemo:
还是有错,不过只剩一个啦。
错误原因:类公有后,被访问的成员也要公有才可以被访问。
所以这个show方法也要用public修饰一下:
再依次讲两个类编译,这次终于没错啦,运行:
成功啦!
总结一下:
包与包之间进行访问,被访问的包中的类以及类中的成员,都需要被public修饰。
不过有一种特殊情况哦。
用例子来说明。
packb包:
packa包中,我们可以用DemoA来继承DemoB:
依次编译DemoB、DemoA、PackageDemo,然后运行起来啦:
有趣的事情来啦,接下来,我可不可以不建立DemoA的对象,直接建立DemoB的对象呢?
运行一下,发现也行呢:
我们发现,packa包中的类和pack包中的类区别不太大呀?它们都能访问packb包中的类。DemoA为什么还有继承DemoB呢,没意思了呀,哼!
#Java小剧场:
PackageDemo:哈哈哈哈,我不把人家叫爸爸我也可以用人家的类呢,哈哈哈哈。
DemoA:呜呜呜呜~
#
所以,Java就给不同包中的子类提供了一个特殊权限。就是,你认我为父,你就能够拿到一些别人拿不到的东西。
这个特殊权限就是。。。噔噔噔噔!protected权限!
这个权限就是保护权限。
我们现在依然在pack包中直接访问packb包中的DemoB,编译运行一下:
出错啦。
#Java小剧场:
DemoB:你必须是我鹅子我才可以叫你访问,否则。。。哼!
PackageDemo:呜呜呜呜~
#
现在用亲儿子来访问它:
编译运行:
OK的啦。
#Java小剧场:
DemoA:爸比对我最好啦!有爸比就是不一样~
DemoB:么么哒( ˘ ³˘)♥
#
总结:
不同包中的子类还可以直接访问父类中被protected权限修饰的成员。
注意:包与包之间可以使用的权限只有两种:public protected。
接下来说一下几种访问权限在不同情境中的访问情况:
关于覆盖:
现在packb包中有两 类,想在PackageDemo中全部建立对象访问:
怎么做呢?
这样可以吗:
不可以。
我们说,类变成公有之后,类名必须和Java文件名保持一致。
现在有两个公有类,Java文件名到底用什么呢?
注意:一个.java文件中,不能出现两个及以上的公有类和接口。
那怎么办呢?
将这两个类分别存在两个.java文件中,但它们依然都是属于packb哦:
分别编译:
都被放在packb文件夹中啦:
,
搞定~
另外,我们这个包还可以有多层次,包里面还可以有包~
比如:
编译后:
注意一下目录,是不是多层的呀,最里面一个文件夹里就是DemoC.class文件啦。
这叫多层包目录。这非常多见的,对类进行逐级管理~
09-面向对象(导入import)
还是用上面的例子:
现在想在PackageDemo中建立DemoC的对象,这样可以吗:
不可以。
应该写上包名:
但是这样建立对象也太费劲了叭!
接下来介绍一个关键字,是因需求而来的关键字哦,它可以帮我们简化类名的书写:import(导入)。
import:导入的是包中的类。
一个例子:
这样在当前包中可以创建DemoA的对象,这个没有问题。那可以创建DemoZ的对象吗?不可以哦。
因为导入的是packb中的类,而haha是packb包中的包。
如果想要创建DemoZ对象,就必须这样导入:
一定要区分清楚哦。
像这种通配符*的写法:
在实际开发中其实不建议用哦。
因为有可能这个包中有十个类,我们只需要使用其中一个类,那把这一个类导入就行啦。需要用到包中的哪个类,就导入哪个类。
但是这样会不会有点麻烦呢?
不用担心。
以后我们开发用的都是高级的编译器(Eclipse之类),不会用记事本的。在高级的编译器中,package是不用自己写的,import也是不用自己写的,全都是自动导入。
注意:如果导入了两个包,这两个包中有同名的类,那在调用类的时候,类前面必须写上包名哦!
那定义包名的时候该怎么定义呢?
我们想想定义包的初衷是什么:方便管理、避免类重名。
所以建立定义包名不要重复,可以使用url来完成定义,url是唯一的。
像这样:
在一个程序中,不写import可以吗?
可以的。
不写import的时候,我们使用到其他包中的类,可以按照全类名方式来写。而import只是可以简化类名的书写。
10-面向对象(jar包)
Java中也有它的压缩包,这个压缩包就是Jar包。
Java压缩包需要一个jdk中的工具来完成,这个工具就叫做jar.exe。
一个例子:
编译运行:
这是jar的一些用法:
创建packa包和pack包的压缩包:
创建好啦:
这个压缩包中有两个包(文件夹):packa和pack。
我们来查看一下它里面的内容:
注意:这个是jar包生成后自动生成的一个文件夹。这个文件夹里面存放了一个配置清单文件,这个配置清单文件里的数据我们是可以改动的,改动完这个jar包会有一些特殊的意义,或者特殊的操作方式。
我们现在先不对这个进行深入了解,在讲图形界面的时候会对它有一些涉猎。
现在我们把pack和pakca文件夹都删掉。
试着运行一下,挂啦:
我们想一想,打压缩包的意义就是这两个压缩包的父目录变成了jar包,而不是原先的C盘的myclass。
我们重新set classpath一下:
再运行,OK啦:
下次拿到一个jar包,我们只需要将jar包定义到classpath中,这样jar包中的东西我们就都可以用啦。
其他的一些用法:
显示详细信息:
更详细了,还有时间:
将a.jar包中的详细信息写在c盘中的1.txt文件中:
将c盘的详细内容写在c盘的2.txt文件中:
后半部分讲的我觉得不是很需要,所以就木有仔细听,也有点繁琐。有提到native:本地方法,这种方法是调用了系统(当前所用系统,比如说Windows),所以看不到方法体。