繁体   English   中英

公共方法返回私有类实例呢?

[英]What about public method returns private class instance?

我正在尝试测试以下情况:

  1. 有一个主要的。 ( city.Main )
  2. 有一个包裹。 package castle
  3. 在包中,有一个公共类( castle.Guard )和一个包私有类( castle.Princess )。
  4. 如果公共类返回私有类的实例怎么办?

这是我的代码:

主程序

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
    }

}

守护程序

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;
    }
}

公主.java

package castle;

class Princess {
    public void sayHi() { System.out.println("Hi world"); }
}

注意main()中的所有 4 条语句都有错误。

我也做了一些研究。 事实上,我想模仿这个答案 但我不明白为什么我的代码会抛出错误。

感谢您的任何解释!


编辑:

我打算将castle-Princess package-private设为私有 我知道,通过从包中返回包私有类,我应该为错误做好准备。 但是为什么这个答案有效,而我的却没有?

Princess类默认作用域为castle包,因此它在city包中不可见。 为了规避:

(我们可以采用以下三种方法之一。)

1) public Princess类并使用它。

package castle;

// added public modifier
public class Princess {
     public void sayHi() { System.out.println("Hi world"); }
}

2) 或者,定义一个public interface并让Princess实现它并使用interface reference而不是class reference 我更喜欢这个。

城堡\\IPrincess.java

// Interface definition
package castle;

public interface IPrincess {
    public void sayHi();
}

城堡 \\ Princess.java

// Implement the interface in Princess class
package castle;

class Princess implements IPrincess {
    public void sayHi() { System.out.println("Hi world"); }
}

城堡\\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;
    }
}

城市\\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();
   }
}

3)或者,将所有类放在同一个包中。

您将无法返回类内私有范围的类型。 如果它是另一个类的私有范围,任何外部来源如何知道该类型是什么?

这个设计甚至不会编译。

编辑:

简单的解决方案是将其公开,然后您可以在包外部使用它。

你试图模仿的答案是有效的,因为所有的类都在同一个包中

如果将UntrustworthyFriendFriend放在不同的包中(如您的场景),也会出现同样的问题。

如果public Princess只能在其包裹外可见:

公主.java

package castle;

public class Princess {
    public void sayHi() { System.out.println("Hi world"); }
}

另外,请确保在Main导入它。

问题在于你的 Princess 类定义中的一个非常小的错误:

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 修饰符,公主类不能在声明它的文件之外访问。

您的示例不同,因为您的类位于不同的包中,并且从 Main 中看不到 Guard 和 Princess。

但是公共方法可以返回私有类的实例。 JDK 有很多例子,这里是java.util.Arrays一个

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
...
private static class ArrayList<E> extends AbstractList<E>  {
...

这就是你要问的。 诀窍是该方法的返回类型是私有类实现的公共接口。 你可以做类似的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM