【问题标题】:Accessing public methods of a Private Inner Class, from outside the Enclosing class从封闭类外部访问私有内部类的公共方法
【发布时间】:2012-11-30 07:01:24
【问题描述】:

我有以下代码类 Agent.java :

 public class Agent {
      Helper helper ;

      private class SpecificBehaviour extends Behaviour{
         private Apple a;
         public SpecificBehaviour(Apple a){
          setApple(a);
          }
          public void setApple(Apple a){
           this.a=a;
          }
          public Apple getApple(){
          return a;
          }
         } 

         public void someMethod(){
         helper = new Helper(this);
        }   

}

在 Helper.java(同一个包中的另一个类)中,我想访问 getApple() 方法。做了一些搜索,发现了这个link 我想知道是否有更好/更简单的方法来做到这一点?

【问题讨论】:

  • 简单 OuterClass.InnerClass innerClass = new OuterClass.new InnerClass();

标签: java private inner-classes


【解决方案1】:

这里至少有两个问题:

  • Helper 不知道SpecificBehaviour 的存在,因为它是一个私有类。它可能可能知道Behaviour 类,您没有提供任何详细信息。如果在Behaviour 中声明了getApple(),并且如果Behaviour 对Helper 可见,那么可见性部分就不会成为问题。
  • Helper 需要引用SpecificBehaviour 的实例,这意味着您需要实例化SpecificBehaviour。为此,您还需要一个Agent 的实例,因为SpecificBehaviour 是一个内部类。不清楚您是否有这样的实例。

基本上,我认为私有内部类的存在在这里增加了混乱。如果您对 Java 相当陌生,我强烈建议您暂时坚持使用顶级类。他们有一些微妙之处,最好一次学习一件事。

如果这没有帮助,请提供更多背景信息 - 目前您的问题非常模糊。 在哪里你想在Helper 中使用getApple? Helper 的部分状态应该是对SpecificBehaviour 实例的引用,还是应该是方法参数?您是否创建了Agent 的实例? Behaviour 是什么样的?您可能会发现,在一次回答一个问题的过程中,您能够更好地自己找出问题所在。

【讨论】:

    【解决方案2】:

    - 使用Composition原理获取getApple()方法的访问权限。

    例如:

    public class Agent {
    
          Apple a = new Apple();     // Agent class has a reference of type Apple.
    
         .....
         .....
     }
    

    - 第二种方法是在Apple 类 中创建getApple() 方法static,然后从Agent 类 访问它使用带有.(点)运算符的类名。

    例如:

      public class Agent {
    
              public void go(){
    
                Apple.getApple();
    
            }
    
             .....
             .....
         }
    

    【讨论】:

      【解决方案3】:

      您需要询问您传递给Helper 的Agent 对象,以获得私有类SpecificBehaviour 的实例。这就是它的工作方式。封装记住。

      【讨论】:

        【解决方案4】:

        Jon Skeet 表示,我完全同意:

        Helper 需要引用 SpecificBehaviour 的实例, 这意味着您需要实例化SpecificBehaviour。为了那个原因, 你还需要一个Agent 的实例,因为SpecificBehaviour 是一个 内部阶级。不清楚你有没有这样的实例。

        其实你可以通过测试下面的示例代码来了解你的尝试有多奇怪:

        Agent.java

        public class Agent 
        {
            private class SpecificBehaviour 
            {
                public String toString()
                {
                    return "specific behaviour";
                }
            }
            public Class getInner() 
            {
                return SpecificBehaviour.class;
            }
        }
        

        Helper.java

        public class Helper 
        {
            public static void main(String[] args) 
            {
                try 
                {
                    Agent agent = new Agent();
                    System.out.println(agent.getInner().newInstance().toString());
                }
                catch (InstantiationException e) {  e.printStackTrace();  }
                catch (IllegalAccessException e) {  e.printStackTrace();  }
            }
        }
        

        上面的代码编译得很好。让我们看看输出是什么:

        java.lang.InstantiationException: Agent$SpecificBehaviour
            at java.lang.Class.newInstance0(Class.java:340)
            at java.lang.Class.newInstance(Class.java:308)
            at Helper.main(Helper.java:5)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-22
          • 2016-09-09
          • 2016-08-04
          • 2014-08-10
          • 2013-09-20
          相关资源
          最近更新 更多