Un campo debe ser estático, cuando sin importar la instancia ese valor deba mantenerse siempre así. Y a lo sumo ser cambiado desde donde se puede (pero para todas las instancias), de no ser así entonces sería preferible que fuera una constante.
Para entenderlo lo mejor es exponer un ejemplo:
He crado una interfaz vehículo... de la que luego he implementado una clase 'bicicleta', la clase bicicleta expone uel miembro estático "número de ruedas", cuyo valor evidente es 2... pués una bicicleta siempre tiene dos ruedas, si tiene otra cantidad será otro tipo de vehículo, no una bici... Si más tarde implemento una clase Triciclo, igualmente a ese campo le asignaría 3 ruedas, y si fuera 'coche' 4....
Ahora bien, supongmaos que tenemos un valor "Kilometros" (recorridos), carece de sentido que ese miembro sea estático... debe ir cambiando contínuamente.
Luego en tu diseño debes saber cuando un campo tiene que ser una constante, cuando estático y cuando variable.
En tu ejemplo, "saldo", es una cantidad que va a estar variando contínuamente, luego carece sentido de ponerle el atributo estático.
El uso más claro para el atributo 'static' suele verse en los métodos/funciones.
Supongamos que independientemente de cual sea la clase de vehículo creado, hay un método Pintar(color), si para todos los tipos de vehículos el método va a hacer siempre lo mismo, se hace estático, lo que en la práctica implica que solo existirá una copia de ese método en memoria y que es compartido por todos y que por supuesto no retiene datos de ninguno en específico, toma lo que se le da, hace el trabajo y lo entrega... internamente (sobre sí, no modifica nada que luego haría fallar algo, por ejemplo no importaría que internamente tuviera un campo que contara cuantos vehículos ha pintado y que se autoincremente con cada invocación, pués eso no interfiere con el trabajo que debe hacer).
Dicho de otra manera, cuando un miembro o método usa el atributo 'static' existe una única dirección para ese miembro/método en todas las instancias y es la misma. si no es 'static' cada instancia posee una dirección de memoria propia del miembro/método es decir es particular.
Es algo así como que en cada ciudad hay un solo alcalde... pero en cada casa habrá (por poner un ejemplo), una madre, un padre y un hijo, ...pero el alcalde, es el mismo para cada casa de dicha ciudad. Así, los miembros/métodos estáticos son compartidos por todas las instancias.
Aquí una ligera explicación (los ejemplos no son precisamente buenos, pero el texto inicial sí):
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Releyéndote, me parece entenderte mejor, pués aclaras que el saldo no es el de un cliente cualquiera si no el del cajero... lo cual por supuesto interesa proteger...
Bien en caso así, nota que lo que necesitas es el "static int SaldoInicial = 900" y luego otro miembro llamado (por ejemplo) "int saldoActual"
Ahora tu externamente operas con tu métodos 'depositar/extraer', pero estos alteran solo el 'SaldoActual' no el 'SaldoInicial'...
Un ejemplo en pseudocódigo para no perderse en detalles del lenguaje y hacerlo engorroso con 500 palabras superfluas...
satic int SaldoInicial = 900
int SaltoActual = 0
getSaldoInicial{
devolver SaldoInicial
}
getSaldoActual{
devolver (SaldoActual + SaldoInicial)
}
void Depositar(int cantidad){
Si (cantidad >0) // no quremos que deposite valores negativos, para el caso mejor declarar 'cantidad' como un entero sin signo, así siempre será positivo.
SaldoActual += cantidad
fin si
}
void Extraer(int cantidad){
Si (cantidad > 0) // no queremos que extraiga valores negativos, para el caso mejor declarar 'cantidad' como un entero sin signo, así siempre será positivo.
Si (getSaldoActual -cantidad) >0)
SaldoActual -= cantidad
Sino
Mensaje "no queda suficiente saldo en depósito en el 'cajero', para realizar la transacción (intente con una cantidad menor)..."
fin si
fin si
}
Como se ve se opera con 'saldoactual'. El campo "saldoActual" inicialmente vale 0, pero al consultarlo suma siempre el valor 900 del campo "saldoInicial", el depósito queda a cero, cuando saldoActual = -900, pués -900 + SaldoInicial = (900-900) = 0
en el mensaje de 'no queda saldo... directamente s ele podría decir cuanto saldo queda, haciendo las cuentas pertienentes
void Extraer(int cantidad){ // no queremos que extraiga valores negativos, para el caso mejor declarar 'cantidad' como un entero sin signo, así siempre será positivo.
int tmp
Si (cantidad > 0)
tmp = (getSaldoActual - cantidad)
Si (tmp >0)
SaldoActual -= cantidad
Sino
tmp = (cantidad - getSaldoActual) //cantidad solicitada es mayor que cantidad en depósito.
Mensaje "No queda en depósito la cantidad solicitada, el máximo que podría extraer ahora mismo del 'cajero' es: tmp ..."
fin si
fin si
}
Por último, nota además como tanto el saldoInicial como el SaldoActual están protegidos para solo ser leídos y no sobreescritos (con de solo lectura, no se proveen métodos de escritura), la única manera de escribir un nuevo valor en SaldoActual es a través de las operaciones: Depositar y Extraer. Y en cuanto a SaldoInicial, lo lógico es que cuando llegare el furgón blindado, si pudiera de nuevo ser modificado (si no, sería una constante), pero para eso debe hacerse con su propio método en su clase y siendo dicho método no accesible por las instancias...