Como que funciona as variaveis como private?

Estou estudando aquela apostila da caelum OO, estou com uma duvida na pagina 57, esta falando que devo proteger os meus atributos com private para que eles nao sejam acessado em um outra classe, no final da pagina estar dizendo que so devo alterar os valores dos atributos atravez dos metodos ? tipo as variaveis que armazena saldo e limite. Que eu nao posso alterar os valores uzando minhaConta.saldo = 1000; em outra classe e sim ultilizando os metodos saca e deposita?

Sim senhor; elas ficam “invisíveis” ou “inacessíveis” para outras classes (mesmo as que herdam da classe que contém as variáveis privadas).
Quando vou explicar essas coisas para alguém e quero que a pessoa não se esqueça nunca mais, costumo dizer que as variáveis e métodos privados são como aquelas partes do corpo que devem sempre ficar cobertas; nem seus filhos (subclasses) ou pais (superclasses) podem vê-las, quanto mais outras pessoas (classes não relacionadas).

Sim as variáveis ficam como privadas (visíveis somente dentro da própria classe), os métodos que acessam elas que devem ser visíveis (public, protected para outras classes.
Então voçê nao seta ou pega diretamente as variáveis, você os métodos get e set para fazerem isso!Iss
Isso é o que chamamos de encapsulamento em OO

thingol eu entendi perfeitamente , so mais uma coisa. As variaveis so vao armazenar os valoeres atravez dos metodos saca e deposita isso?

Variáveis com modificador de acesso private indicam que elas só podem ser acessadas no escopo da classe, para que elas possam ser acessadas por classes externas você deve criar métodos publicos que manipulem essas variáveis (métodos gettters e setters).

Isso é um conceito de encapsulamento, você deve fazer isso para proteger sua variável para que o valor dela não seja modificado sem autorização prévia.

Ex: sem encapsulamento

[code]class A {

//variavel declarada como publica, ou seja todo mundo poderá enxerga-la
public int vulneravel = 1;

}

class B {

public void static main(String…args){

A a = new A();
//valor da variavel é modificado diretamente
a.vulneravel = 30;

System.out.println(a.vulneravel);
}
}[/code]

Ex: Com encapsulamento

[code]class A {

//variavel declarada como private, ou seja todo mundo poderá enxerga-la somente através dos métodos
private int naoVulneravel = 1;

public int getNaoVulneravel() {

return naoVulneravel;
}

public void setNaoVulneravel(int n) {

if (n < 30)
naoVulneravel = n;

}

}

class B {

public static void main(String…args){
A a = new A();

//valor da variavel é modificado através de métodos publicos

a.setNaoVulneravel(30);
System.out.println(a.getNaoVulneravel());
}
}[/code]

Considerei que ambas as classes estão no mesmo pacote, é claro que encapsulamento vai muito além disso mas é só para exemplificar e você entender o modificador private.
No método que modifica o valor da variável você pode colocar algum tipo de validação também para ela não aceitar qualquer valor, no exemplo a variável encapsulada so receberá valores menores que 30, no exemplo não encapsulado você não tem essa proteção.

Espero ter ajudado.

Exatamente; você restringiu o acesso a elas (declarando-as como “private”), e então liberou o acesso só através de métodos que podem enxergá-las.

Voltando ao exemplo que é para ficar “chumbado” na sua cabeça, esses tais métodos de acesso são como as roupas que cobrem essas partes privadas (como um biquíni); você não pode enxergar as tais partes, só as roupas que as cobrem.

Vc tentou fazer um exemplo?

class Conta{ private int salario; } class Teste { public static void main (String [] xxx) { Conta c = new Conta(); c.salario = 10; } }

Se tentar compilar:

Teste.java:5: salario has private access in Conta c.salario = 10;

Existem muitos motivos que te levam a não expor a propriedade salario diretamente, e uma delas é polimorfismo.

Imagine que vc tem diversos tipos de Conta e todas implementam uma Interface comum, ContaComum por exemplo.

[code]interface ContaComum{
int getSaldo();
void saque(int valor);
}
class ContaDeTesteNaoUtilizar implements ContaComum {
int getSaldo(){return 0;}
void saque(int valor){}
}

class ContaDeVerdade implements ContaComum {
private int saldo;
int getSaldo(){return this.saldo;}
void saque(int valor){
if(valida(valor)){
this.saldo = this.saldo - valor;
}
}
private boolean valida(int valor) { return (this.saldo - valor) >= 0; }
}


public void processaTransacaoSaque(ContaComum conta,int valor){
LOG.write("Depositando " + valor);
conta.saque(valor);
}
[/code]

Perceba que eu posso passar para processaTransacaoSaque tanto uma ContaDeTesteNaoUtilizar, quanto uma ContaDeVerdade. E, ao depositar numa conta de verdade eu tenho uma validação dos valores, para não ficar com saldo negativo (esse tipo de conta não permite). Eu posso ter um tipo de conta com limite mas processaTransacaoSaque não precisa lidar com isso, pois vc não precisa alterar o limite ou consulta-lo na hora de um saque: alias eu não testei se o saque sera negativo (criando dinheiro na minha conta) mas isso é o tipo de melhoria que vai surgindo no modelo.

Polimorfismo é algo bem interessante e vc vai ver num futuro em breve, qualquer coisa procure aqui:

http://guj.com.br/artigos.jsp

Alias, ContaComum é uma interface e não uma Classe pq eu não quero forçar a herança, apenas garantir um contrato de que estas classes tem um getSaldo e um deposita(valor)

Deu para entende perfeitamente obrigado pela ajuda de todos vcs. Um Grande abraço e um bom final de semana para todos.