简体   繁体   中英

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)

Smiply declare the class Sate inside the class Walker :

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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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