【问题标题】:Arrays with outer and inner classes具有外部类和内部类的数组
【发布时间】:2013-08-04 23:51:08
【问题描述】:

我对 Java 比较陌生。我想创建一个外部类的数组列表,并且对于数组列表的外部类的每个索引,我想要一个内部类的数组列表。

public Outerclass{

    //Code Here

    public InnerClass{
    //Code Here
    }
}

//My attempt at setting up the arrays
public ArrayList <Outerclass> olist;
public ArrayList <InnerClass> ilist;


 olist= new ArrayList<Outerclass>();
 for (int i = 0; i < 3; i++) {
      Outerclass c = new Outerclass ();
      ilist = new ArrayList<InnerClass>();
      for(int j = 0 ; j < 4; j++){
          InnerClass e = new InnerClass();
          ilist.add(e);
      }
      olist.add(c);
 }

这行得通吗?

【问题讨论】:

  • 你尝试的时候发生了什么?
  • 这行不通。外部类中需要有内部类数组。
  • 我该怎么做@tbodt?
  • 内部类的实例是否需要维护对外部类实例成员的引用?如果不是,则将内部类设为static,并将其视为顶级类。
  • @JimGarrison 是的,内部类需要维护对外部类实例成员的引用

标签: java oop inner-classes outer-classes


【解决方案1】:

首先,我认为你应该在开始跑步之前学会走路:

public Outerclass

应该是

public class Outerclass

与内部相同!

其次,您的代码的所有最后部分都应该在 main() 方法 INSIDE Ourclass 中。

第三,不,你不能像那样使用内部类,这就是为什么这些类是内部的。如果您想从main() 内部或外部类外部使用内部类,则必须使用外部实例才能访问它们,就像访问任何其他实例成员一样 - 您不能直接访问它:

        Outerclass oc = new Outerclass();
        Outerclass.InnerClass in = oc.new InnerClass();

【讨论】:

  • 谢谢!当我复制我的代码时,我可能应该更清楚一点。我将如何为内部类参数化我的 Arraylist。是 ArrayList 还是 ArrayList
【解决方案2】:

对答案 #2 稍作改进,如果您有用于数据存储的嵌套类,则意味着您有一个外部类的构造函数,该构造函数会自动为内部类生成可变数量的数组成员,例如树结构。该解决方案实际上是一种解决方法,它使用一个已定义的成员 - ArrayList - 稍后可以扩展它,而不是在 OuterClass 中直接定义 InnerClass[] 数组,如果它不是静态的,它将不起作用。

public class OuterClass
{
    private int NumberInnerClassInstances;       
    // ... other members of OuterClass
    ArrayList<InnerClass> innerClassInstances = new ArrayList<>();

    OuterClass( input vars ...)  {
        // calculate the NumberInnerClassInstances needed
        for(int i = 0 ; j < NumberInnerClassInstances; i++) {
            OuterClass.InnerClass in = this.new InnerClass(i);
            innerClassInstances.add(in);
        }
    }

    public class InnerClass
    {
        int icvar;
        InnerClass(int i) {
            //...construct the Inner Class Member #i
            // can access the members of OuterClass
        }
    }
}

然后,您可以使用 get 访问 InnerClass 实例:

oc = new OuterClass( vars ...)
var = oc.InnerClassInstances.get(i).icvar

【讨论】:

    【解决方案3】:

    以下是代码的关键行:

     Outerclass c = new Outerclass ();
    
         InnerClass e = new InnerClass();
    

    那是行不通的。你会得到一个编译错误。

    由于InnerClass 是一个内部类,它需要在其封闭类的实例的上下文中进行实例化(即OuterClass)。像这样:

     Outerclass c = new Outerclass ();
    
         InnerClass e = c.new InnerClass();
    

    c.new ... 形式称为限定类实例创建表达式;见JLS 15.9

    注意事项:

    1. 如果创建内部类的代码位于外部类实例的上下文中(例如,它位于外部类的实例方法中),则无需限定 new像这样。

    2. 如果InnerClassstatic,这也不是必需的。但是根据标准 Java 术语,InnerClass 是嵌套类而不是内部类。

    【讨论】:

      【解决方案4】:

      内部类的实例只能存在于外部类的实例中。 (有关静态和非静态内部类的区别,请参阅this answer 了解更多信息)。

      这意味着你创建了内部对象外部对象。您可以将其视为创建并包含内部对象的外部对象(因此得名 inner

      这是一个例子:

      import java.util.ArrayList;
      
      public class OuterClass {
          static ArrayList<InnerClass> innerClasses = new ArrayList<InnerClass>();
      
          public static void main(String[] args) {
              OuterClass oc1 = new OuterClass();
              OuterClass.InnerClass ic1 =  oc1.new InnerClass();
              OuterClass.InnerClass ic2 =  oc1.new InnerClass();
              innerClasses.add(ic1);
              innerClasses.add(ic2);      
              System.out.println(innerClasses.size());
          }
          class InnerClass {
      
          }
      }
      

      【讨论】:

        【解决方案5】:

        鉴于InnerClass 需要保持对OuterClass 成员的引用,我想知道为什么不将ArrayList&lt;InnerClass&gt; 放在OuterClass 中。如果它们以这种方式组成,那么将列表由OuterClass“管理”并为其提供访问方法以返回InnerClass 实例列表等会更有意义。

        所以是这样的:

        public class OuterClass
        {
           private List<InnerClass> innerClassInstances = new ArrayList<>;
        
           public void addInnerInstances(int count)
           {
              for(int j = 0 ; j < count; j++)
              {
                 InnerClass e = new InnerClass();
                 innerClassInstances.add(e);
              }
           }
        
           public List<InnerClass> getInnerClassInstances()
           {
               return innerClassInstances;
           }
        
           public class InnerClass
           {
             //...
           }
        }
        
           //in your main class or wherever
           List<Outerclass> olist;
        
           olist= new ArrayList<Outerclass>();
           for (int i = 0; i < 3; i++) 
           {
              Outerclass c = new Outerclass ();
              c.addInnerInstances(4);
              olist.add(c);
           }
        

        您不能像您正在做的那样使用new 自己创建InnerClass,您是说它需要访问其OuterClass 实例的成员,正如您在代码中看到的那样,每个new InnerClass() 你永远不会以任何方式指定它的OuterClass 实例。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-26
          • 2011-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多