使用引用变量封装数组

时间:2014-12-16 17:40:45

标签: java arrays encapsulation

我打算编写一个程序来模拟一个或多个维度中的粒子碰撞。对于2D情况,我还想制作一个显示粒子的GUI。

我有一个主要类ParticleCollider,它包含一个内部类Particle,一个包含所述Particles的数组,以及一些用于更新粒子位置和速度的方法。该课程大致如下:

class ParticleCollider {

     class Particle {
          private double mass;
          private double[] pos;
          //plus some other private class variables
          public Particle(double mass, double[] pos) {
               this.mass = mass; 
               this.pos = pos;
          }
     }

     private Particle[] pArray;

     //Details of constructor are irrelevant
     public ParticleCollider() {

     }

     //Do stuff to particles in pArray, i.e. change their positions and velocitites
     public void update() {
          //For example
          pArray[0].pos[0] = 0;
     }

}

在图形课程中,我希望能够访问Particles,以便我可以找到他们的位置和半径用于绘图目的。一种方法当然是在getParticles中添加方法ParticleCollider以返回ParticlespArray的数组。我现在的问题是,这是否会被视为违反封装。由于Particle类没有setter,我无法更改Particles。此外,因为数组有固定的长度,我不能添加任何Particles。我唯一可以做的就是取一些Particle并为其赋值null

修改 有人建议我使用List而不是数组,并为所述List提供迭代器。在我看来,这不会解决封装问题。无论如何,我不愿放弃数组,因为我需要能够在Particle的集合中选择一个随机Particles,然后循环迭代它。

1 个答案:

答案 0 :(得分:1)

使用这种模式怎么样:

    public class Particle {
        // Particle code
    }

    public class Particles implements Iterable<Particle> {
        ArrayList<Particle> myParticles = new ArrayList<Particle>();

        public void add(Particle particle) { myParticles.add(particle); }

        public Iterator<Particle> iterator() {
            return myParticles.iterator();
        }

        // more code on particles
    }

    void bla() {
        Particles particles = new Particles();
        particles.add(new Particle());
        particles.add(new Particle());

        for (Particle particle : particles) {
            System.out.println("P="+particle);
        }
    }

如果要禁止此迭代器上的remove(),可以使用以下模式:

    public static class Particles implements Iterable<Particle> {
        ArrayList<Particle> myParticles = new ArrayList<Particle>();

        public void add(Particle particle) { myParticles.add(particle); }

        public Iterator<Particle> iterator() {
            return new Iterator<Particle>() {
                Iterator<Particle> listIterator = myParticles.iterator();

                @Override
                public boolean hasNext() {
                    return listIterator.hasNext();
                }

                @Override
                public Particle next() {
                    return listIterator.next();
                }

                @Override 
                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }

    }