JAVA:编译运行含有包层的类、同包和不同包类的相互访问、不同包子类和父类的访问权限

1.编译运行含有包层的类

  • java中,为了确保类名的唯一性,以及方便组织自己的代码,引入了包package。
  • package语句必须放在程序代码的第一行,除注释之外。
  • 在某一程序代码的首行,如果没有package语句,代码仍然可以编译,编译后的class文件被存放在默认包中,即与java文件同目录。
  • 《JAVA编程思想》中这样写到:“Java将这样的文件自动看作是隶属于该目录的默认包之中,于是它们为该目录的其他文件都提供了包访问权限。”即该默认包中的其他文件是可以访问这些文件(“这样的文件”)的。
  • 提供一个例子,如何编译和运行含有包层的类:
package com.access;

class PrintString
{
    void print()
    {
        System.out.println("Hello World!");
    }
}
public class TestPackage 
{
    public static void main(String[] args) 
    {
        PrintString ps = new PrintString();
        ps.print();
    }
}
  • 编译:javac -d . TestPackage.java 其中:-d表示自动生成包层 . 表示这个包层是在当前目录下建立。
  • 运行:java com.access.TestPackage
  • 输出:Hello World!
    这里写图片描述
  • 注意:
    (1)package com.access; 表示把该文件的所有的类放入com.access这个包中,并且该文件所有类的真正名字将是包名和类名的组合。例如,类TestPackage 的名字将编程com.access.TestPackage ,而不再是TestPackage 。
    (2)编译时建议使用:javac -d . TestPackage.java 尽量不要使用javac TestPackage.java 因为后者要手动的建立包目录。
    (3)如果不再当前路径下运行程序,则必须保证class文件的最上层目录的父目录位于classpath下。

  • 例如:包的父目录是D:\JavaProject\demo12。现在要在C:\Users\Administrator目录下运行TestPackage。实现步骤如下:
    (1)设置环境变量:C:\Users\Administrator> set classpath=d:\JavaProject\demo12;注意:classpath=d:\JavaProject\demo12这部分没有空格。
    (2)运行:C:\Users\Administrator> java com.access.TestPackage
    JAVA:编译运行含有包层的类、同包和不同包类的相互访问、不同包子类和父类的访问权限_第1张图片

  • 注意:
    (a)classpath:设置的是可运行的class文件的路径。在任何路径下都可以导入包中的类,此时就需要设置classpath,
    classpath:即设置的导入的类的路径
    (b)set classpath:查看当前环境变量classpath的设置
    (c)设置路径:set classpath=导入类文件的包的父目录; //不要把包层的目录放进去
    (d)java access.ChocolateChip2解析: 先检测当前目录下是否有access这个包(包即文件夹),如果有,再检测该包下是否有access.ChocolateChip2这个类;如果没有,编译器将再去classpath设置的路径中依次查找是否有access这个包(包即文件夹),如果有,再检测该包下是否有access.ChocolateChip2这个类。如果都查找失败,则运行出错。

2.同包和不同包类的相互访问

1.同包类的相互访问

  • 一个类可以使用所属包中的所有类,以及其他包中的共有类(public class)。即只有公有类才能被另外一个包访问。
  • 在同一个包中,可以相互访问具有包权限的类和成员。具有包权限的类,即使其成员是公有的,也不能被其他包所访问。具体请见:JAVA——java中类的public class与class的区别详解

2.不同包类的相互访问

  • 访问方式一:不使用import语句
  • 在“编译运行含有包层的类”这一节中讲到,将类放入包中,类的真正的名字就变为:包名和类名的组合。
package access.cookie2;

public class Cookie
{
    public Cookie()
    {
        System.out.println("Cookie constructor");
    }
    public void bite()
    {
        System.out.println("bite");
    }
}  
package access;

public class ChocolateChip2
{
    public ChocolateChip2()
    {
        System.out.println("ChocolateChip2 constructor");
    }

    public static void main(String[] args)
    {
        ChocolateChip2 x = new ChocolateChip2();

        access.cookie2.Cookie y = new access.cookie2.Cookie();//包名和类名的组合,要使用Cookie类,就必须冠以全名。
        y.bite();       
    }
}
  • 编译、运行:
D:\JavaProject\demo11>javac -d . Cookie.java ChocolateChip2.java

D:\JavaProject\demo11>java access.ChocolateChip2
ChocolateChip2 constructor
Cookie constructor
bite
  • 访问方式二:使用import语句
  • import:即类的导入方法,import语句是一种引用包含在包中的类的简明描述。access.cookie2.Cookie y = new access.cookie2.Cookie();这个写法很不简洁。一旦使用了import语句,在使用类时,就不必写出包的全名了。
  • 可以使用import语句导入一个特定的类或整个包。例如:import java.util.*;导入java.util包中所有的类。import java.util.Date;导入java.util包中Date这一特定类。
  • import语句应该位于源文件的顶部,但是位于package语句的后面。
  • 只能使用*导入一个包,而不能使用import java.*或import.java.*.*导入一个一java为前缀的所有包。
package access.cookie2;

public class Cookie
{
    public Cookie()
    {
        System.out.println("Cookie constructor");
    }
    public void bite()
    {
        System.out.println("bite");
    }
}  
package access;
import access.cookie2.*;

public class ChocolateChip2
{
    public ChocolateChip2()
    {
        System.out.println("ChocolateChip2 constructor");
    }

    public static void main(String[] args)
    {
        ChocolateChip2 x = new ChocolateChip2();

        Cookie y = new Cookie();
        y.bite();       
    }
}

3.不同包子类和父类的访问权限:protected 继承访问权限

  • 对于默认访问权限(包访问权限)的类,可以被这个包中的其他类访问;
  • 对于继承了具有包访问权限的成员的类的子类,如果该子类和父类唯一同一个包中,子类可以访问父类中的默认访问控制成员。
package access.cookie2;

public class Cookie
{
    public Cookie()
    {
        System.out.println("Cookie constructor");
    }
    void bite()
    {
        System.out.println("bite");
    }
}  
package access;
import access.cookie2.*;

public class ChocolateChip2 extends Cookie
{
    public ChocolateChip2()
    {
        System.out.println("ChocolateChip2 constructor");
    }
    public void chomp()
    {
        bite();
    }

    public static void main(String[] args)
    {
        ChocolateChip2 x = new ChocolateChip2();
        x.chomp();
    }
}
  • 编译、运行:
D:\JavaProject\demo11>javac -d . Cookie.java ChocolateChip2.java
ChocolateChip2.java:13: 错误: 找不到符号
                bite();
                ^
  符号:   方法 bite()
  位置: 类 ChocolateChip2
1 个错误
  • 由于子类和父类不在同一个包中,且方法bite()具有包访问权限,因此子类是访问不到成员bite()的,故编译错误。
  • 将做如下改进:
package access.cookie2;

public class Cookie
{
    public Cookie()
    {
        System.out.println("Cookie constructor");
    }
    protected void bite()
    {
        System.out.println("bite");
    }
}  
  • 编译、运行:
D:\JavaProject\demo11>javac -d . Cookie.java ChocolateChip2.java

D:\JavaProject\demo11>java access.ChocolateChip2
Cookie constructor
ChocolateChip2 constructor
bite
  • 原因:protected修饰的成员方法,可以被同一个包的其他类访问,同时也能被不同包中的子类访问。但是对于其他包中的类而言,却是private的。

  • 以上是针对方法bite()没有重写的情况而言的。如果在子类对bite()进行了重写,以上的问题就不会存在了。说明子类访问的本类重写以后的方法bite,而不是父类的方法bite。

  • 验证protected修饰的成员,不在同一个包,不存在继承时,对于其他包中的类而言,却是private的。

package access.cookie2;

public class Cookie
{
    public Cookie()
    {
        System.out.println("Cookie constructor");
    }
    protected void bite()
    {
        System.out.println("bite");
    }
}
package access;
import access.cookie2.*;

public class ChocolateChip2
{
    public ChocolateChip2()
    {
        System.out.println("ChocolateChip2 constructor");
    }

    public static void main(String[] args)
    {
        ChocolateChip2 x = new ChocolateChip2();

        Cookie y = new Cookie();
        y.bite();       
    }
}
  • 编译、运行:
D:\JavaProject\demo11>javac -d . Cookie.java ChocolateChip2.java
ChocolateChip2.java:48: 错误: bite()可以在Cookie中访问protected
                y.bite();
                 ^
1 个错误

你可能感兴趣的:(Java,EE)