Java语法_面向对象_包
Java Package
package 关键字
在 Java 中,
package
是一个非常重要的概念,用于组织和管理 Java 类。
定义与作用
定义:
package
语句是 Java 源文件中的一个特殊语句,用于声明该文件中定义的类所属的包。- 它必须是源文件中的第一条非注释语句。
作用
组织代码结构:将相关的类、接口等组织在一起,形成一种层次化的命名空间,使代码更易于管理和维护。
比如,所有与数据库操作相关的类可以放在一个名为
com.example.db
的包中。
避免命名冲突:不同的包中可以有相同名称的类,通过包名来区分它们。
例如,
java.util
包和java.sql
包中都有Date
类,通过完整的包名来明确使用的是哪个类。
声明与命名规则
声明语法:
在 Java 源文件的开头使用
package
关键字来声明包,例如package com.example.myapp;
,表示该文件中的类都属于com.example.myapp
包。命名规则:
- 全小写:包名通常采用全小写字母,以提高可读性和遵循 Java 的命名规范。
- 域名倒置:一般以公司或组织的域名倒置作为包名的开头,然后根据项目的结构和功能进行细分。例如,域名为
example.com
,那么包名可能是com.example.projectname.module
。 - 避免使用关键字:不能使用 Java 中的关键字作为包名,如
class
、public
等。
示例
创建一个叫做animals的包。通常使用小写的字母来命名避免与类、接口名字的冲突。在 animals 包中加入一个接口(interface)
Animal.java文件代码
:1
2
3
4
5
6package animals;
interface Animal {
public void eat();
public void travel();
}接下来,在同一个包中加入该接口的实现
MammalInt.java文件代码
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package animals;
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}然后,编译这两个文件,并把他们放在一个叫做animals的子目录中。 用下面的命令来运行:
1
2
3$ mkdir animals
$ cp Animal.class MammalInt.class animals #将这两个文件放在animals文件夹,也就是animals包下。
$ java animals/MammalInt #这是在命令行中执行MammalInt类。java是 Java 虚拟机(JVM)的启动命令,用于运行 Java 类。这里指定了animals/MammalInt,表示要运行animals目录下的MammalInt类。输出
1
2Mammal eats
Mammal travel或者在把这两个文件放在 手动新建的
animal
文件夹 下,然后在IntelliJ IDEA Community Edition 下直接运行MammalInt.java
即可,可实现相同功能。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29PS C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\包> tree /F
卷 OS 的文件夹 PATH 列表
卷序列号为 1511-5760
C:.
├─.idea
│ .gitignore
│ misc.xml
│ modules.xml
│ vcs.xml
│ workspace.xml
│ 包.iml
│
├─animals
│ Animal.java
│ MammalInt.java
│
└─out
└─production
└─包
├─.idea
│ .gitignore
│ misc.xml
│ modules.xml
│ vcs.xml
│ 包.iml
│
└─animals
Animal.class
MammalInt.class
上述代码中,MammalInt
类实现了Animal
接口,并实现了eat
和travel
方法,在方法中分别打印出了Mammal eats
和Mammal travels
。
package 的目录结构设置
首先,在.java的文件中,如果想要使用package <name>
语句,那么必须将该文件放到 ./<name>
文件夹 (项目根目录的name文件夹) 下。
示例1
通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 Mihoyo.com,所有的包名都以 com.Mihoyo 开头。包名中的每一个部分对应一个子目录。
例如:有一个 com.Mihoyo.test 的包,这个包包含一个叫做 Mihoyo.java 的源文件,那么相应的,应该有如下面的一连串子目录:
1 | ....\com\Mihoyo\test\Mihoyo.java |
那么文件Mihoyo.java
如下:
1 | package com.Mihoyo.test; |
如果使用javac -d . Mihoyo.java
编译文件,就会产生如下字节码文件:
1 | .\com\Mihoyo\test\Mihoyo.class |
编译之后的 .class 文件应该和 .java 源文件一样,它们放置的目录应该跟包的名字对应起来。
但是,并不要求 .class 文件的路径跟相应的 .java 的路径一样。你可以分开来安排源码和类的目录。比如:
1 | <path-one>\sources\com\Mihoyo\test\Mihoyo.java |
这样,你可以将你的类目录分享给其他的编程人员,而不用透露自己的源码。
字节码文件的加载路径
用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到你程序中使用的所有类型:
- 类目录的绝对路径叫做
class path
。设置在系统变量CLASSPATH
中。也可以在执行时使用java -classpath <class path>
来指定或者直接更改CLASSPATH
。(更改方法在下一个示例中) - 编译器和 java 虚拟机通过将
<package name> + <class path>
来构造 .class 文件的路径。
比如在上一个示例中:
<path- two>\classes
是class path
<package name>
是com.Mihoyo.test
- 所以最终 编译器和 JVM 会在
<path-two>\classes\com\Mihoyo\test
中找编译好的 .class 文件。
一个 class path 可能会包含好几个路径,多路径应该用分隔符(;
)分开。
默认情况下,编译器和 JVM 查找 当前目录。JAR 文件按包含 Java 平台相关的类,所以他们的目录默认放在了 class path
中。
默认的CLASSPATH如下:
1 | ClassPath=.;C:\Program Files\Java\jdk-17\lib\dt.jar;C:\Program Files\Java\jdk-17\lib\tools.jar;C:\Program Files\Java\jdk-17\lib; |
示例2
使用集成开发环境IDE IntelliJ IDEA Community Edition
运行java文件时,包以及java文件编译后,默认存放在./out/production/<根目录名称>下,比如:
1 | PS C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\包> tree /F |
这是如果想要在另一个文件夹下使用这个包,有两种方法:
本地库的使用方法
方法一:命令行执行指定包路径
命令行执行,指定包路径C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\包
即可:
1 | PS C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\本地库和外部库> java -classpath C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\包\out\production\包 .\OutLib.java |
方法二:更改变量CLASSPATH
在 CMD 中追加 CLASSPATH
1 | C:\Users\19707>set CLASSPATH |
上述命令中,%CLASSPATH%
会获取当前 CLASSPATH
的值,然后通过分号 ;
将新的路径追加到后面。
或在 PowerShell 中追加 CLASSPATH
1 | $env:CLASSPATH = "$env:CLASSPATH;C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\包\out\production\包" |
这里,$env:CLASSPATH
表示当前 CLASSPATH
的值,通过字符串拼接的方式将新的路径追加到后面。
效果如下:
1 | C:\Users\19707\iCloudDrive\iCloud~md~obsidian\Happy\quzia_pac\Java_prac\本地库和外部库>tree /f |
import 关键字
Java包的导入与使用
- 导入其他包中的类:
- 使用
import
语句导入其他包中的类,以便在当前类中可以直接使用这些类,而无需使用完整的包名 - 例如,要使用
java.util.Date
类,可以在代码中添加import java.util.Date;
,然后就可以直接使用Date
来创建对象等操作。 - import 语句应该位于 package 语句之后
- 使用
- 使用不同包中的同名类:
- 当需要使用不同包中的同名类时,可以使用完整的包名来明确指定要使用的类。
- 例如,
java.util.Date
和java.sql.Date
是两个不同的Date
类,如果在代码中同时需要使用这两个类,可以通过完整的包名来区分它们。
示例
在项目下创建文件_Import.java
如下:
1 | import animals.MammalInt; //使用包中的类,该类是公共的,本文件对它有访问权限。 |
执行后也输出
1 | Mammal eats |
包与访问控制
- 访问修饰符与包的关系:Java 中的访问修饰符(public、private、protected和默认(没有修饰符))用于控制类、方法和变量在不同包中的访问权限。
public
:被public
修饰的 类、方法或变量 可以在 任何包中的任何类 中被访问。private
:private
修饰的成员只能在 当前类内部 被访问,即使在同一个包中的其他类也无法访问。protected
:protected
修饰的成员可以在 当前类、同一个包中的其他类以及不同包中的子类 中被访问。- 默认(没有修饰符):没有修饰符的成员具有包访问权限,即只能在同一个包中的类中被访问。