Java面向对象_07_包机制


1. 包机制的基本介绍

最开始提到过,一个文件中只能出现一个public类,并且建议一个文件写一个类。那么一个项目肯定会涉及到很多类,并且不同的类有着不同的紧密联系,这些类该怎么管理呢?

和电脑中的文件夹一样,比如有很多个电影,属于不同类型,有恐怖片、喜剧片、爱情片等等。为了更方便的查找影片,就会建立不同的文件夹,将这些电影归档到不同的文件夹里面。同理,在Java中,为了方便管理不同的代码文件,需要将其归档到不同的文件夹中,这个文件夹就叫做package

package也被称为包机制,其作用就是为了方便程序的管理,不同功能的类存放在不同的包下,即不同的包具有不同的功能。

2. package关键字

package关键字的语法如下:

1
2
3
4
package 包名;

// 例子如下
package cn.com.sina.www;

注意,package关键字只能出现Java程序的第一行。包名一般采用公司域名倒序的方式,因为公司域名具有全球唯一性。包名也可看作是文件夹的层级关系。

包名:公司域名倒序+项目名+模块名+功能名

注意,带有package关键字的Java程序编译和运行怎么办?

带有package关键字的java程序按照以前的运行方法运行失败,提示找不到或无法加载主类。因为关键字指明了本文件的所在目录是package,比如package cn.com.sina.www.javatest;,则指明该文件HelloWorld.java所在的目录是cn/com/sina/www/javatest/,也就是最终的类名cn/com/sina/www/javatest/HelloWorld

而我们用原始的命令行方法编译的时候,仅仅是生成class文件,不会生成具体的目录,所以如果是用命令行编译的话,就需要手动创建目录,将class文件移动到包目录下,编译的之后指定具体的路径即可。**但是这样做,太复杂,可以javac -d . HelloWorld.java**,-d就是带目录编译,.表示在当前目录。这样就会自动生成了包目录。

除此之外,可以直接使用IDE,它们自带了这种功能,可以直接建立包package。

3. import关键字

在有了package关键字之后,可以看到完整的类名就是加上了包名。所以如果再一个类文件中创建另一个类对象,此时需要完整的类名。但是如果两个类在同一个包下,可以仍然像之前那样做。

1
2
3
4
5
6
7
8
9
package cn.com.sina.www.javatest;

public class HelloWorld{

public static void main(String[] args){

System.out.println("Hello world!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package cn.com.sina.www.javatest;

// 同一个包下,可以不写完整类名,仅写后缀
public class PackageTest01{

public static void main(String[] args){

// 全名
cn.com.sina.www.javatest.HelloWorld hw01 = new cn.com.sina.www.javatest.HelloWorld();
System.out.println(hw01);

// 后缀名
HelloWorld hw02 = new HelloWorld();
System.out.println(hw02);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
package cn.com.sina.www.javatest02;

// 不同包下,使用类,必须写全名。
public class PackageTest02{

public static void main(String[] args){

cn.com.sina.www.javatest.HelloWorld hw = new cn.com.sina.www.javatest.HelloWorld();

System.out.println(hw);
}
}

但是,这样做太复杂了,不可能在引用其他包中的类时,要把包名写全。所以就需要关键字import了。即将需要的类导入到本包中,这样在创建类的时候,就不需要写包名了。

import语句用来完成导入其他类,同一个包下的类不需要导入,不在同个包下需要手动导入。import语句需要编写到package语句之下,class语句之上。

  1. import什么时候用?

    A类中使用B类。

    A类和B类都在同一个包下,不需要import。

    A类和B类不在同一个包下,需要使用import。

    注意,java.lang是Java语言的核心类,其中的类是系统自动导入的,不用手动导入。比如String就是lang中的一个类,不需要手动导入。

  2. import怎么用?

    import语句只能出现在package语句之下,class声明语句之上。

    除了下面的用法,也可以import cn.ac.ucas.javatest.*,即将javatest中的所有类都导入过来。注意,*只能表示类,不能import cn.ac.*,或者说不能导入包,只能导入class类。

导入语法格式:

  • import 类名; 注意,这里的类名指的是包含包名的完整路径
  • import 包名.*;
1
2
3
4
5
6
7
8
9
10
11
12
13
package cn.com.sina.www.javatest02;
import cn.com.sina.www.javatest.HelloWorld;

public class PackageTest02{

public static void main(String[] args){

// cn.ac.ucas.javatest.HelloWorld hw = new cn.ac.ucas.javatest.HelloWorld();
HelloWorld hw = new HelloWorld();

System.out.println(hw);
}
}

4. 简单案例

主要是用import测试权限修饰符,类之间的关系如下所示:

oop_03.png (154×130) (gitee.io)

其中CuteCat继承了Cat类,TinyCat仅仅和Cat属于同一个包

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
29
30
31
32
package animal;

public class Cat {
private double height;
private double weight;

public Cat(){

}

public Cat(double height, double weight){
this.height = height;
this.weight = weight;
}

// 四种权限修饰的不同方法。
public void eating(){
System.out.println("猫儿在吃鱼!");
}

protected void moving(){
System.out.println("猫儿在走猫步!");
}

void sleep(){
System.out.println("猫儿在睡觉!");
}

private void watching(){
System.out.println("猫儿在观望!");
}
}
1
2
3
4
5
6
7
8
9
10
11
package animal;

public class CuteCat extends Cat {

public void doSome(){
this.eating(); // public,任何可访问
this.moving(); // protected,子类可访问
this.sleep(); // 缺省,同包下可访问
// this.watching(); // private只能本类中访问
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package animal;

public class TinyCat {

private Cat cat;

public TinyCat(){}

public TinyCat(Cat cat){
this.cat = cat;
}

public void doSome(){
this.cat.eating(); // public,任何可访问
this.cat.moving(); // protected,同包下可访问
this.cat.sleep(); // 缺省,同包下可访问
// this.cat.watching(); // private只能本类中访问
}
}

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
package person;
import animal.Cat;

public class Chinese {
private String name;
private double height;
private double weight;
private Cat cat;

public Chinese(){}

public Chinese(String name, double height, double weight, Cat cat){
this.name = name;
this.height = height;
this.weight =weight;
this.cat = cat;
}

public void doSome(){
this.cat.eating();
// this.cat.moving(); // protected 只能是本类、同包、子类中访问。
// this.cat.sleep(); // 缺省,只能本类以及同包下访问
// this.cat.watching(); // private,只能本类访问。
}
}

5. 备注

参考B站《动力节点》。


文章作者: 浮云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 浮云 !
  目录