1)为什么在Java包中的文件中我应该在其中编写“包”内容?它没有间接地假设如果它在目录中,那么它在包中?。
2)我来自C ++世界。我总是从其他使用该类的文件中导入我需要的类的.h(我的意思是,我只想“显示”标题,而不是实现)。但现在我对Java的进口感到有些困惑。这是如何在Java中完成的?
由于
答案 0 :(得分:7)
不,这不是假设的。毕竟,我的包裹叫什么? com.mypackage.stuff? src.com.mypackage.stuff? myproject.com.mypackage.stuff? C.Users.makakko.workspace.myproject.src.com.mypackage.stuff?
如果您只将文件夹从文件夹中删除,它是否相对于驱动器根目录?如果项目是在不同机器上的不同驱动器号上开发的,该怎么办?它是否相对于javac.exe的位置?再次,不同的安装目录呢?运行javac时工作目录怎么样?但是你可以为javac指定一个位置来查找你的源文件。如果你想做一个简单的测试程序,或者教一个以前从未编程过的Java,怎么办?你必须使用/解释包结构的整个概念吗?
如果省略package
说明符,那么您仍然在一个包中。它只是“默认包”,没有名称。
头文件更多地是来自C编译方式的工件而不是实现信息隐藏的方式。在C中,必须先定义一个方法,然后才能引用它。如果你想要有几个相互引用的方法,你必须在使用它们之前定义所有这些方法,因此标题。 C ++中的标题从中延续,但C ++的变化改变了标题的必要性。
在Java中,编译器会在执行任何需要方法/类的操作之前查看所有方法和类签名。 header提供的函数被放入编译器本身。您不能依赖标题来隐藏信息,因为
代码可以放在头文件中
除非您使用真正的信息隐藏(例如单独的库),否则程序员可以找到与标题匹配的c / cpp文件而不会出现问题
同样在Java中,您只能通过删除源来隐藏真实信息。一旦您无法访问源代码,就会使用公共/受保护的类,枚举和接口公开API。对于奖励积分,请为所有内容编写解释性JavaDoc注释,并在源代码上运行javadoc.exe,以便为将使用您的软件包的任何人生成单独的文档。
答案 1 :(得分:5)
1)package
声明必须与项目中的目录层次结构相匹配。
如果我在package com.stackoverflow.bakkal;
中使用Car.java
,则需要以下层次结构。
com/
|-- stackoverflow/
| `-- bakkal/
| |-- Car.java
2)如果要隐藏实现,可以在Java中使用interface
而不是class
。然后在.class
文件或JAR中分发实际的实现。
嗯,但接口不能 实例化......
界面在某种程度上像C ++中的原型一样工作。你有合同,然后实际的实施来自其他地方。
我想实例化一个类,但是 没有给出实施, 只有原型
即使是C ++,也是不可能的,如何在没有实际实现的情况下实例化某些东西?在C ++中,您仍然需要链接到目标文件。在Java中,您使用.class
个文件。
答案 2 :(得分:3)
不假设包,因为Java的哲学是明确而不是隐式/假设。
它确实使您能够访问当前包中的任何内容,但需要明确导入任何外部内容。 (我相信Java.lang是个例外,因为它包含很多基本功能,比如String,不会有一个不会使用它的包。)
这也是你倾向于看到的原因:
import java.util.ArrayList;
import java.util.LinkedList;
而不是:
import java.util.*;
这有点令人讨厌,直到有一天你试图找出别人的代码而且它会让你知道如果事情被隐藏/暗示会有多难。
如果您使用Eclipse,Netbeans或IntelliJ,您将永远不会注意到两个功能。
首先,如果在输入类名的过程中点击ctrl-space,它不仅会为你完成类名,而且还会自动将它添加到导入列表中。
其次,如果你到达导入的地方“错误”或者你不使用ctrl-space扩展,你可以输入ctrl-shift-o(eclipse)来“修复导入”。这将自动导入需要导入的内容并删除不再需要的导入。根据您的设置,它也会展开或折叠*。
一旦你关闭系统,你甚至不会考虑进口。
答案 3 :(得分:1)
包指定了类的路径。它必须与磁盘上的目录或jar(zip)中的目录匹配。位置相对于类路径上的位置。受保护的访问仅限于同一包中的类。
您可能在.h文件中执行的一些操作是在类定义中完成的。常量属于一个类,可能是公开可见的。在.h中,常数必须是公开可见的。
导入相当于包含.h,但有助于处理同名冲突定义的问题。您只能包含一个项目或类中的所有可见项目。也可以跳过导入并使用包名称为您正在访问的类的前缀添加前缀。
通过导入实际上看不到实现(至少不超出编译类提供的实现。可见的是可见接口公共方法和数据。对于从相同包中导入的方法和没有指定访问权限的数据(public / protected / private)也是可见的。受保护的方法和变量对类的子类是可见的.h文件可以在不提供源文件或目标文件的情况下使用.Imports要求提供指定的类。(一个类可能包含只有常数,虽然这将是糟糕的设计。)