Enviar um café pro programador

Pode me ajudar a transformar cafeína em código?

set e get: o que são e como usar esses métodos de forma correta

Vamos aprender nesta aula de nosso curso online de Java os dois métodos mais usados pelos programadores Java: os getters e setters.

O que são e para que servem os métodos get e set

get e set nada mais são que métodos, que freqüentemente vemos em classes de Java.
Eles servem para pegarmos informações  de variáveis da classe que são definidas como 'private', porém esses método são definidos como 'public'.

Daí surge uma pergunta natural: por que criar métodos para acessar variáveis, se podemos acessar elas diretamente?
Simples: questão de segurança.

As variáveis 'private' só podem ser acessadas de dentro da Classe. É como se elas fossem invisíveis foram do escopo da classe/objeto. Assim, evitamos que outros métodos, classes ou hackers tenham acesso aos dados de determinada classe, que muitas vezes podem ser dados privados, como é caso de aplicações para empresas e bancos.

Como tratar, então, essas variáveis?
Aí que entra a questão dos métodos. Vamos permitir o acesso a essas variáveis, claro (senão não haveria sentido em usar esses atributos).
Porém, vamos ter um total controle sobre essas variáveis através dos métodos.

Por exemplo: suponha que você tenha que criar uma aplicação para um banco, onde vai limitar o número de saques de um cliente.
Os valores do saldo desse cliente ficarão armazenados na variável 'saldo'. Se você der acesso total a essa variável, o cliente poderia usar de forma descontrolada os serviços do banco.

Porém, podemos criar um método em que, cada vez que o cliente saque dinheiro ele ative um contador:

public void setSaque(double valor){
saldo -= valor;
contador++;
}


Nesse trecho de código, quando o usuário tenta sacar, através do menu do caixa eletrônico, ele vai para o método 'saque()'.
Então cada vez que ele saca, seu saldo diminui em 'valor' e um contador (que é uma variável da classe) é incrementado. É impossível fugir desse método!
Sacou? O contador roda! Sempre!

Sabemos que temos um limite diário de saque, vamos supor que seja três. Então vamos limitar o número de saques:
public void setSaque(double valor){
if(contador <=3){
saldo -= valor;
contador++;
   } else {
System.out.println("Você atingiu o limite de saques diários");
   }
}

Pronto. Se você sacar 3x, o contador terá valor 4 (supondo que seu valor inicial seja 1), e agora é impossível ele sacar mais, pois sempre vai cair no else.
No próximo artigo criaremos uma aplicação que simula um banco.

Como usar os métodos get e set

Usamos get para obter informações. Esse tipo de método sempre retorna um valor.
Usamos set para definir valores. Esse tipo de método geralmente não retorna valores.

Usando o exemplo da classe "Funcionario", do artigo passado sobre this e uso de métodos em Classe e Objetos, temos o código:



getSet.java


public class getSet{
    
    public static void main(String[] args){
        String nome = "Neil Peart";
        int ID=2112; 
        double salario = 1000000;
        
        Funcionario chefe = new Funcionario();
        
        chefe.setNome(nome);
        chefe.setID(ID);
        chefe.setSalario(salario);
        
        chefe.exibir();
    }

}


Funcionario.java


public class Funcionario {
    private String nome;
    private int ID;
    private double salario;
    
    public void exibir(){
        System.out.printf("O funcionário %s, de número %d recebe %.2f por mês", getNome(),getID(),getSalario());
    }
    
    public void setNome( String nome ){
        this.nome = nome;
    }
    
    public void setID( int ID ){
        this.ID = ID;
    }
    
    public void setSalario( double salario ){
        this.salario = salario;
    }
    
    public String getNome(){
        return this.nome;
    }
    
    public int getID(){
        return this.ID;
    }
    
    public double getSalario(){
        return this.salario;
    }
}

Como invocar métodos de dentro do construtor

Outra maneira de inicializarmos as variáveis de um Objeto, é usando os métodos 'set', direto do construtor:

setGet.java


public class setGet{
    
    public static void main(String[] args){
        String nome = "Neil Peart";
        int ID=2112;
        double salario = 1000000;
        
        Funcionario chefe = new Funcionario(nome, ID, salario);
        
        chefe.exibir();
    }

}


Funcionario.java


public class Funcionario {
    private String nome;
    private int ID;
    private double salario;
    
    public Funcionario( String nome, int ID, double salario){
        setNome(nome);
        setID(ID);
        setSalario(salario);
    }

    public void exibir(){
        System.out.printf("O funcionário %s, de número %d recebe %.2f por mês", getNome(),getID(),getSalario());
    }
    
    public void setNome( String nome ){
        this.nome = nome;
    }
    
    public void setID( int ID ){
        this.ID = ID;
    }
    
    public void setSalario( double salario ){
        this.salario = salario;
    }
    
    public String getNome(){
        return nome;
    }
    
    public int getID(){
        return ID;
    }
    
    public double getSalario(){
        return salario;
    }
}

Uso errado do get e set

Qual a diferença entre alterar e pegar o valor de uma variável diretamente (caso ela seja pública), e alterar e pegar o valor dela através de set e get (se ela for privada) ? Não é segurança, já que podemos alterar seu valor como bem quisermos, através dos métodos set.

Definir get e set para todas as variáveis, de forma direta, é um exemplo de péssimo hábito de programação. Infelizmente é uma técnica bem comum e muitos programadores, até os mais experientes, cometem esse ato inútil.

Para que servem então? Quando usar?
Só use set e get quando você for fazer algo além de simplesmente mudar o valor de uma variável 'private'.
Lá no começo de nosso tutorial, usamos o exemplo de contador, que limita o número de saques de um cliente a um caixa eletrônico.

Outro exemplo disso, seria em um aplicativo de vendas.
Ao comprar, o método set ou get automaticamente define o valor de desconto ou juros. Assim esse método faz algo mais além do que mudar a variável. Assim, sua aplicação se torna robusta e segura, pois se torna impossível mudar o valor da variável sem que seja alterada o valor do juros ou desconto.

Sempre que seu método set do tipo for:
retorno metodo(tipo valor){
this.nome_da_variavel = valor;
}

Muito provavelmente ele é inútil. Para saber quando usar é simples: use quando for fazer algo além de fornecer valor.

Um exemplo util:
retorno metodo(tipo valor){
this.nome_da_variavel = valor * juros;
};

Vamos treinar!

Exercício: Caixa Eletrônico em Java - Caixa.java
Crie um protótipo de caixa eletrônico em Java. No início, ele pede seu nome e valor $$ inicial que tem na conta. O programa deve fornecer um número de 4 dígitos - número da conta - para o usuário (use Random). Esses dados serão usados para criar um objeto da classe "Conta.java"

A seguir, mostra um menu com as opções (esse menu deverá ser um método):
- Extrato: exibe o nome, número da conta, saldo e quantos saques já foram realizados
- Sacar: recebe o valor a ser sacado, informa se pode ser sacado (não pode ficar negativo) e mostra o saldo
- Depositar: recebe o valor a ser depositado e mostra o novo saldo
- Sair

Esse menu aparece até o usuário escolher sair. As outras opções são métodos que devem fazer parte da "Conta.java" (setters e getters). Note que o usuário pode sacar no máximo 5 vezes por dia.

Solução comentada

17 comentários:

TON-GAMER disse...

Muito bom. vai ser bem útil.

TON-GAMER disse...

Muito bom... bem explicado e me será bem útil.

Jessica disse...

Obrigada, tá bem explicado mesmo.

Unknown disse...

muito pratico e simples de aprender... valeu ai pessoal

Anônimo disse...

Não entendi muito bem =/

Apostila Java Progressivo disse...

Olá Anônimo,

Pode nos dizer o que você não entendeu bem?

Anônimo disse...

muito bom e pratico, toda teoria deveria vir acompanhada de uma pratica assim como vc faz, valeu obrigado !

Unknown disse...

Olá....
Gostaria de agradecer Muito o trabalho de vocês... o site está excelente....

gostaria de entender a funcionalidade do Get e Set... pois criei uma classe cliente (para o programa do caixa) e consegui fazer o caixa funcionar legal... talvez precise de um ou outro ajuste... mas não consegui fazer o metodo que criei na main puxar o saldo do metodo set ou get na classe cliente para fazer um print do saldo que ficaria depois do saque....
fiz de forma direta...
assim achei que a classe cliente e o metodo get e set estão muito acessórios ainda..
não entendi direito...

Apostila Java Progressivo disse...

Olá Alexandre,

Bem, vamos lá. Não entendi direito o que você fez.

A main() é um método, e você criou outro método na main?

Ou você criou um método dentro da classe principal que tem a main()?
Se for esse o caso, lembre-se que quando cria um objeto (que não é estático) dentro de um método, ele 'morre' lá dentro.

Então se tu criou um objeto na main(), e quer tratar ele em outro método, tem que passar esse objeto pro outro método.
Aí você pode usar normalmente os set e get desse objeto.

Como você fez?

Unknown disse...

Obrigado pessoal pela disponibilidade....
Eu estou estudando este assunto de Set e Get e não havia entendido direito... desde que comecei o curso essa é a segunda vez que preciso procurar em outro lugar para entender melhor....
acho isso muito bom... pois foram muitas aulas meu net beans já está na septuagésima aplicação(heheheheh)...
o que eu não havia entendido era para que funcionava o get e Set.... e por isso não estava conseguindo usa-los bem e estava achando eles muito acessórios...
agora percebi que o set serve para mudar uma váriavel private de alguma classe diferente da main, e o get para que vc consiga acessar algum atibuto private de outra classe, sem poder retornar seu valor....

Mas apesar desta dificuldade de entendimento sou muito grato a boa vontade e disposição da equipe do Java progressivo... vcs são sensacionais,.....

Atenciosamente
Alexandre

Werner disse...

Excelente!
"this", "set", "get"... tudo ficou muito abstrato na aula de java na facul... Agora sim, com explicação clara começo a entender. O negócio é praticar e praticar...
Parabéns pelo site e pela dedicação.

Unknown disse...

Ficou imenso, nem sei se tá "Padrão fifa" mas funciona, é só coloca no bloco de notas e compila;
_______________________________
Caixa.java
import java.util.Scanner;
import java.util.Random;
public class Caixa{
public static void main (String[] args){
//variaveis
String nome;
double valor_inicial;
int numero_conta=1;
Scanner entrada=new Scanner(System.in);
Random gerador_Aleatorio=new Random();
//recebe dados
System.out.println("Insira o nome do cliente");
nome=entrada.nextLine();
System.out.println("Insira o valor inicial da conta: ");
valor_inicial=entrada.nextDouble();
numero_conta=gerador_Aleatorio.nextInt(10000);

if (numero_conta<1000){
numero_conta=gerador_Aleatorio.nextInt(10000);
}
//seta os valores para class cliente
Cliente usuario=new Cliente();
usuario.setNome(nome);
usuario.setValor_Inicial(valor_inicial);
usuario.setNumero_Conta(numero_conta);

usuario.Menu();


}
}
___________________________________
Cliente.java
import java.util.Scanner;
public class Cliente{

//variaveis
private String nome;
private double valor_inicial;
private int numero_conta;
public int opcao;
public int contador=1;
public Scanner entrada=new Scanner(System.in);

/*exibe dados
public void Exibe(){
System.out.println("O Cliente "+getNome()+" tem um valor inicial

de "+getValor_Inicial()+" e numero de conta "+getNumero_Conta());
}*/

//menu
public void Menu(){

Scanner entrada=new Scanner(System.in);
System.out.println("Selecione uma opção:");
System.out.println("1-Saque");
System.out.println("2-Extrato");
System.out.println("0-Sair");
opcao=entrada.nextInt();
if(opcao==0){
System.out.println("Obrigado por utilizar nossos serviços");
} else {
do {
switch(opcao){
case 1:
Saque();
Menu();
break;
case 2:
Extrato();
Menu();
break;
default:
System.out.println("Opção inválida!");
}
}while(opcao!=0);
}
}

//metodo saque
public void Saque(){
System.out.println("Insira o valor a ser sacado: ");
double valor_saque=entrada.nextDouble();
if (contador<=5){
contador++;
valor_inicial-=valor_saque;
System.out.println("SaldoR$ " + valor_inicial + " numero de

retiradas efetuadas "+(contador-1));
} else {
System.out.println("Atingido quantidade maxima de saques!");
}
}
//metodo Extrato
public void Extrato(){
System.out.println("\n\n\n\n");
System.out.println("Extrato:");
System.out.println("Nome do titular: "+getNome());
System.out.println("Numero da conta: "+getNumero_Conta());
System.out.println("Saldo: R$"+ getValor_Inicial()+" número de

retiradas efetuadas: "+(contador-1));
System.out.println("\n\n\n\n");
}
//metodo sair
public void Sair(){
System.out.println("Obrigado por utilizar nossos serviços!");
}

//metodos set para atribuir valor e retornar
public void setNome(String nome){
this.nome=nome;
}
public String getNome(){
return nome;
}

public void setValor_Inicial(double valor_inicial){
this.valor_inicial=valor_inicial;
}
public double getValor_Inicial(){
return valor_inicial;
}

public void setNumero_Conta(int numero_conta){
this.numero_conta=numero_conta;
}
public int getNumero_Conta(){
return numero_conta;
}


}

Anônimo disse...

Putz, valew mesmo, tava apanhando para entender o conceito dos Setters e Getters,
Com esta aula foi simples de entender...
Valew

Unknown disse...

Muito bom este curso, estou acompanhando ele bem do inicio, porem agora chegando em Orientação Objeto parte II as coisas estão complicando. Inicialmente com os get e sets para mim ficou confuso a real utilização deles...

Unknown disse...

Uma dúvida se eu setar um valor na variável eu consigo acessar ela via get em outra classe ?

Thyago Neves disse...

Não sabia nada sobre programação, estou começando do zero, e decidi começar por java porque um tempo atrás quis aprender a desenvolver aplicativos para android, e descobri que é preciso aprender java antes.

Mas mesmo sendo meu primeiro contato com esse mundo da programação e com o java estou gostando muito e quero elogiar vocês pelo trabalho, consegui aprender muita coisa e entendi com facilidade as primeiras seções e aulas do curso JavaProgressivo. Mas - talvez por não ter conhecimento anterior de programação - comecei a ter muita dificuldade quando entrei na parte de Metodos com parâmetros e sem parâmetros, ainda não entendi completamente qual a diferença entre eles e como criá-los... Mas vou voltar e reler tudo denovo, até conseguir entender. Quero aprender para poder trabalhar com isso no futuro (Embora não saiba quanto tempo leve para saber o suficiente para pegar algum trabalho como programador java...).
Não tenho condições no momento de fazer um curso pago (apesar de que, pelo que venho lendo nos comentários, esse curso é melhor do que muitos cursos pagos em questão de qualidade), por isso agradeço pela oportunidade que estão concedendo não só a mim como também a outras pessoas que estão na mesma condição, sei que já ouvem muito isso mas aqui vai mais um: "Parabéns pela iniciativa!" rs

Eloy Vanco disse...

PARA QUEM GOSTA DA BANDA RUSH VAI ADORAR SEU EXEMPLO

Contribuir com o Java Progressivo

Que tal apoiar e fazer crescer o ensino da programação no Brasil ?

Ajudar nosso país a crescer e se desenvolver cada vez mais, tecnologicamente?

Clica abaixo pra saber mais!

Apoiar o Projeto Progressivo


Tutoriais de Java