edave
edave

Reputation: 188

Access private field of inner classes

I am trying to make it possible to pass the state of an object to the "outside", so it can be restored later by passing it back, but without disclosing the private state to the outside world. In Java, I could do this with an inner class:

class Walker {
    class State {
        private int pos;

        private State (int p) {
            pos = p;
        }
    }

    private int pos = 0;

    State setState () {
        return new State(pos);
    }

    void setState (State s) {
        pos = s.pos;
    }
}

However, if I try the same in Scala, it says that Walker#setState may not access State#pos.

class Walker {
  private var pos = 0

  def state = new Walker.State(pos)
  def state_= (s: Walker.State) {
    pos = s.pos
  }
}

object Walker {
  class State (private val pos: Int)
}

How do I archive the same thing as in Java? (Other that cloning the object)

Upvotes: 0

Views: 237

Answers (2)

roterl
roterl

Reputation: 1883

In Scala each outer class instace has it's own inner classes type, which mean outer1.inner.getClass != outer2.inner.getClass.
It isn't clear from your question if you need to if you need to have the same State class for all the Walkers (for example to assign walker1 state's to walker2), or not. I assume that you do want it to have same class type. All you need to so is to define the State in the Walker companion object as private[Walker]:

class Walker {
  private var pos = 0

  def state = new Walker.State(pos)
  def state_= (s: Walker.State) {
    pos = s.pos
  }
}
object Walker {
  class State (private[Walker] val pos: Int)
}

val w1 = new Walker                               //> w1  : demos.Walker = demos$Walker@4fccd51b
val w2 = new Walker                               //> w2  : demos.Walker = demos$Walker@475530b9
w1.state = w2.state

What it does is to define the State's pos as private to all but the Walker. See more about it here.

If you don't need the State to be the same between Walker instances then you can move the State definition into the class itself with scoped to the outer class: private[Walker] class State (private[Walker] val pos: Int)

Upvotes: 2

Jean Logeart
Jean Logeart

Reputation: 53859

Smiply declare the class Sate inside the class Walker:

class Walker {
    class State(pos: Int) {
        // other functionnalities
    }
    // use State
}

Upvotes: 2

Related Questions