java当一个类包含packagelevel方法时,如何将该类隐藏在接口后面?
如何将以下类隐藏在接口后面(并使用工厂对其进行实例化)?:
public class TreeNode {
private List<TreeNode> children;
private TreeNode parent;
public void addChild(TreeNode newChild) {
children.add(newChild);
newChild.setParent(this);
}
public TreeNode getParent() {
return parent;
}
public void removeChild(TreeNode child) {
children.remove(child);
child.setParent(null);
}
void setParent(TreeNode newParent) {
if(parent != null) {
parent.removeChild(this);
}
parent = newParent;
}
}
假设您将该类重命名为TreeNodeObj,并让它实现TreeNode接口:
class TreeNodeObj implements TreeNode {
private List<TreeNode> children;
private TreeNode parent;
public void addChild(TreeNode newChild) {
children.add(newChild);
newChild.setParent(this);
}
... etc. ...
}
public interface TreeNode {
public void addChild(TreeNode newChild);
public void removeChild(TreeNode child);
public TreeNode getParent();
}
public class NodeFactory {
public static TreeNode createTreeNode() {
return new TreeNodeObj();
}
}
这段代码不会编译,因为setParent()没有在TreeNode接口中定义(因为不应该直接调用它,也不应该在包外部公开)
我能想到的唯一解决办法是进行以下修改:
public interface TreeNode extends TreeNodePackageAccess {
public void addChild(TreeNode newChild);
public void removeChild(TreeNode child);
public TreeNode getParent();
}
interface TreeNodePackageAccess {
void setParent(TreeNode newParent);
}
class TreeNodeObj implements TreeNode {
…[previous code]…
public void setParent(TreeNode newParent) {
// this method is made public in order to implement TreeNodePackageAccess
…[previous code]…
}
}
有没有比使用上述策略更好的方法来实现这一点?(此外,使用上述策略,setParent()仍然可以通过反射从包外部访问,因此从技术上讲,您甚至无法使用它实现包级封装。)
如果接口需要一个不应该公开的包级方法,那么如何将原始类隐藏在接口后面
# 1 楼答案
只要在需要的地方将其转换为实现类。如果TreeNode的任何实现不是TreeNodeObj,则抛出一个异常,表明它来自无效的提供程序
JavaSE已经做到了这一点。从the documentation of the java.nio.file package
因此,该包中的其他类可以执行以下操作:
# 2 楼答案
如前所述,这里没有什么特别的要求。可以使用接口抽象类的public方法的任意数量,包括零。在任何一般意义上,类的所有方法都不必镜像为接口的抽象方法
但您的意思似乎是希望在接口中表示一个或多个包访问方法,这是不可能的。接口方法只能是
public
或private
,并且private
方法不是抽象的。抽象方法的实现不能缩小其访问范围,因此抽象接口方法的实现必须是public
您将接口拆分为包访问超级接口和公共子接口的想法毫无帮助,即使您最终愿意将实现方法公开。superinterface声明的任何方法都会被子接口继承,并可以通过它进行访问