我正在尝试测试以下情况:
city.Main
)package castle
)castle.Guard
)和一个包 - 私有类(castle.Princess
)。这是我的代码:
Main.java
package city;
import castle.Guard;
public class Main {
public static void main(String[] args) {
Princess princess = Guard.getPrincessStatic();
// Error: Princess cannot be resolved to a type
Guard.getPrincessStatic().sayHi();
// Error: The type Princess is not visible
Guard guard = new Guard();
guard.getPrincess().sayHi();
// Error: The type Princess is not visible
guard.getPrincessMember().sayHi();
// Error: The type Princess is not visible
}
}
Guard.java
package castle;
public class Guard {
public Princess getPrincess() {
return new Princess();
}
public static Princess getPrincessStatic() {
return new Princess();
}
private Princess m_princess = new Princess();
public Princess getPrincessMember() {
return m_princess;
}
}
Princess.java
package castle;
class Princess {
public void sayHi() { System.out.println("Hi world"); }
}
请注意main()
中的所有4个语句都有错误。
我也做了一些研究。实际上我想模仿this answer。但我不知道为什么我的代码会抛出错误。
感谢您的解释!
我打算将castle-Princess
包 - 私有。我知道从包中返回一个 package-private 类,我应该为错误做好准备。但为什么that answer有效,但我的却没有?
答案 0 :(得分:5)
Princess
类默认作用于castle
包,因此在city
包中不可见。规避:
(我们可以采取以下三种方法之一。)
Princess
类public
并使用它。package castle;
// added public modifier
public class Princess {
public void sayHi() { System.out.println("Hi world"); }
}
public interface
并让Princess
实施它并使用interface reference
代替class reference
。我更喜欢这个。castle \ IPrincess.java
// Interface definition
package castle;
public interface IPrincess {
public void sayHi();
}
castle \ Princess.java
// Implement the interface in Princess class
package castle;
class Princess implements IPrincess {
public void sayHi() { System.out.println("Hi world"); }
}
castle \ Guard.java
// Modify the Guard class
package castle;
public class Guard {
public IPrincess getPrincess() {
return new Princess();
}
public static IPrincess getPrincessStatic() {
return new Princess();
}
// for here i use Princess instead of IPrincess. (@midnite)
private Princess m_princess = new Princess();
public IPrincess getPrincessMember() {
return m_princess;
}
}
city \ Main.java
// Modify the main class
package city;
import castle.Guard;
import castle.IPrincess;
public class Main {
public static void main(String[] args) {
IPrincess princess = Guard.getPrincessStatic();
Guard.getPrincessStatic().sayHi();
Guard guard = new Guard();
guard.getPrincess().sayHi();
guard.getPrincessMember().sayHi();
}
}
答案 1 :(得分:1)
您无法返回类中私有作用域的类型。任何外部资源如何知道那个类型甚至IS是否属于另一个类的私有范围?
这种设计甚至不会编译。
修改:
简单的解决方案是将其公开,然后您可以在包外部使用它。
答案 2 :(得分:1)
您尝试模仿的答案有效,因为所有类都在同一个包中。
如果您将UntrustworthyFriend
和Friend
放在不同的软件包中(与您的方案一样),则会出现同样的问题。
Princess
只能在public
<强> Princess.java 强>
package castle;
public class Princess {
public void sayHi() { System.out.println("Hi world"); }
}
另外,请务必将其导入Main
。
答案 3 :(得分:0)
问题在于公主类定义中的一个非常小的错误:
package castle;
class Princess {
public void sayHi() { System.out.println("Hi world"); }
}
一开始看起来很好,但是你在课程名称之前错过了public
修饰符:
package castle;
//here!
public class Princess {
public void sayHi() { System.out.println("Hi world"); }
}
如果没有public修饰符,则无法在声明它的文件之外访问公主类。
答案 4 :(得分:0)
您的示例有所不同,因为您的班级位于不同的包中,而Guard和Princess在Main中不可见。
但是公共方法可以返回私有类的实例。 JDK有很多例子,这里有一个来自java.util.Arrays
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
...
private static class ArrayList<E> extends AbstractList<E> {
...
这就是你问的问题。诀窍是方法的返回类型是私有类实现的公共接口。你可以做类似的事情。