Setters & Getters ou Construtores

Olá pessoal,
venho da programação estruturada e estou pastando para entender POO.
Estou no começo do meu curso JAVA e estou vendo agora Setters, Getters, e os métodos (já sei que há quem não concorde que são métodos) construtores.
Meu, é muita coisa pra gravar na cabeça… Isso pq estou no começo… Imagino o que vem poraí…
Bom, mas qual dos dois? Se eu consigo fazer o meu programinha de iniciante com os Set´s e Get´s, qual a vantagem ou desvantagem de se utilizar os construtores? No final, achei mais fácil utilizar o construtor do Set, e o toString para os Get´s…
Alguém pode me ajudar? Obrigado!

Cara… estas confuso com a palavra Construtor…

Vamos la. Construtor no Java é um método que é executado sempre quando um Objeto é criado. Ele é o primeiro método a ser executado numa classe, a nao ser que você tenha criado algum parâmetro nele e chame o Construtor padrão. Enfim, não vou me ater nisso agora pra não complicar.

Os construtores sempre tem que ter o mesmo nome da Classe, inclusive com as maiusculas, e nunca um tipo de retorno.

Por exemplo

public class MinhaClasse {
    public MinhaClasse(){}
}

Quanto aos getters e setters, são convenções JavaBeans para encapsulares teus atributos privados, com o objetivo de prover alguma validação antes de setares algum valor. Servem pra nao deixarem teus atributos públicos e acessiveis diretamente por terceiros.

Ex

public class MinhaClasse{
    private String meuAtributo;

    public String getMeuAtributo() { 
        return this.meuAtributo; 
    }

    public void setMeuAtributo(String meuAtributo) { 
        // Podes validar o valor que estao tentando colocar no teu atributo aqui...
        this.meuAtributo = meuAtributo; 
    }
}

Tem quem diga que podes inicializar os valores dos Objetos na criação dos mesmos, ou seja, no Construtor, mas eu mesmo só usei esse recurso uma única vez…

Abs :wink:

Você criar um getter ou um setter simplesmente pelo fato de criar não tem sentido. É mais fácil passar o valor dos atributos via construtor…
Pense na entidade com um pouco mais de complexidade, se vc for disparar algum evento ao setar algum atributo ai sim pode começar a ser interessante a utilização de getters e setters…

Os construtores são inicializados quando a classe é instanciada!

Os getter and setters server para o encapsulamento, garantindo a integridade das informações.

public class Teste {
Teste() { //metodo construtor

}

Teste(String a) { //metodo construtor com parametros

}
}
//exemplo de getters and setters
public class Teste2 {
private String teste;

public void setTeste(String teste) {
this.teste = teste;
}

public String getTeste() {
return teste;
}
}

xD~~

Quanto ao toString() como get, pensa comigo…

Tens uma Classe com 15 atributos… Qual dos gets seria o teu toString() ???

Precisas de um Objeto que ainda nao sabes o que vais setar nele na hora da criacao… vais colocar o que no construtor para iniciar teu campo ???

Vc deve usar o que faz sentido. As vezes vc nao quer alterar o estado interno de um objeto, logo vc só recebe os valores pelo contrutor ou metodo de fabricação/builder e só tem metodos de leitura.

[quote=peczenyj]Vc deve usar o que faz sentido. As vezes vc nao quer alterar o estado interno de um objeto, logo vc só recebe os valores pelo contrutor ou metodo de fabricação/builder e só tem metodos de leitura.

[/quote]

Eu uso por exemplo em objetos que são um punhado de atributos, inicializo eles somente com o construtor, agora se meu objeto vai ser mutavel, somente ai eu crio setters.

a não ser entidades de persistencia, Hibernate FDP xD

Eu so precisei settar os atributos no Construtor em uma unica situacao… quando peguei um Sistema pra dar manutencao e o mesmo criava os Objetos direto com HQL passando os atributoss pro Construtor… no mais, sempre Get e Set… se bem que eram entidades JPA anotadas e IOD pelo Spring… :roll:

uma coisa que deve ser entendida antes de tudo é o porque de um construtor.

um construtor deve ser usado quando algum objeto necessita de alguma informação para existir, ou seja, sem aquela informação o objeto nao tem consistencia, nao tem sentido, entao nao pode ser criado. A segunda utilidade para o construtor é apenas facilitar a criação de um objeto, assim, quem está o criando nao precisa chamar inumeros metodos setters.

por exemplo a classe File, não pode ser instanciada com um construtor padrão. isso é obvio, pois um File tem que apontar para algum arquivo para realizar as operações.

ja a classe Jframe possui um construtor padrao, pois nao necessita de nenhuma informaçao adicional para existir, mas tem um construtor que recebe uma String para que assim que vc estiver a criando, tambem estara atribuindo seu titulo

Resumindo:
Se seu objeto necessita de “informações” obrigatorias para existir vc deve criar um construtor.

caso essas informaçoes sejam opcionais pode-se fazer um construtor apenas para facilitar sua criaçao e entao seus setters.

abrasssssssssssss

Na verdade, o que eu gostaria de entender, é porque posso programar de duas formas:

Seguem as 2 classes da primeira forma, e depois as 2 classes da segunda forma. Vejam:

PRIMEIRA FORMA:

public class Livro {

private String titulo;
private String autor;
private int paginas;

public Livro () {
}
public Livro (String titulo, String autor, int paginas){
	this.titulo=titulo;
	this.autor=autor;
	this.paginas=paginas;		
}
public String toString(){
	return "Nome do Livro: " + titulo +
	"\nNome do autor: " + autor +
	"\nNº de págs: " + paginas;
}

}

import javax.swing.JOptionPane;

public class TesteLivro {

/**
 * @param args
 */
public static void main(String[] args) {
	
	Livro livro = new Livro(JOptionPane.showInputDialog("Digite o nome do livro"),
							JOptionPane.showInputDialog("Digite o nome do autor"),
							Integer.parseInt(JOptionPane.showInputDialog("Digite o número de páginas")));
	
	JOptionPane.showMessageDialog(null, livro.toString());

}

}

SEGUNDA FORMA

public class Livro {

private String titulo;
private String autor;
private int pagina;

public Livro (){
}
public void setTitulo(String titulo){
	this.titulo = titulo;
}
public String getTitulo(){
	return titulo;
}

public void setAutor(String autor){
	this.autor = autor;
}

public String getAutor(){
	return autor;
}

public void setPagina(int pagina){
	this.pagina = pagina;
}

public int getPagina(){
	return pagina;
}

}

import javax.swing.JOptionPane;

public class TestaLivro {

public static void main(String[] args) {
	
	Livro livro = new Livro();
	
	livro.setTitulo(JOptionPane.showInputDialog("Digite o titulo do livro: "));
	livro.setAutor(JOptionPane.showInputDialog("Digite o nome do autor: "));
	livro.setPagina(Integer.parseInt(JOptionPane.showInputDialog("Digite o número de páginas: ")));

	
	JOptionPane.showMessageDialog(null, "Título do Livro: "+livro.getTitulo()
									+ "\nAutor do Livro: "+livro.getAutor()
									+ "\nNº de Páginas: "+livro.getPagina());

}

}

1 curtida

Existe para sua praticidade, é flexibilidade :smiley:

Tudo que é vital para classe deve ser passado obrigatoriamente via construtor. Se a sua classe depende de um atributo para ter sentido e você não passa o valor desse atributo no construtor ela pode ficar em um estado inconsistente.

Adicione os métodos acessores(os getters and setters) para as propriedades que são mutáveis. Se um estado da classe tem valor A, porém amanhã pode ter seu valor alterado para B, você deve disponilizar um meio de isso ocorrer e uma das formas é via getters and setters.

Um exemplo que utiliza construtores e getters and setters:


public class Ponto {
    private int x;
    private int y;
    
    public Ponto(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

}

Como você pode ver, eu decidi que é obrigatório informar explicitamente um valor para o meu ponto logo de início. Isso não era necessário, pois os atributos x e y tem valor 0 caso não recebam atribuição, porém podemos dizer que por medidas de segurança resolvemos obrigar a pessoa a colocar 0,0 como argumento para ter certeza que é realmente isso que ela quer.

Vale lembrar que existe um set e um get para todas as propriedades, mas ali até que faz sentido. Como já dito em outros posts, só se deve criar getters and setters quando eles realmente são úteis. Você poderia trocar os dois setters por um método moverPara(int x, int y), que atualizaria ambos os pontos, caso achasse necessário. Você poderia fazer também que o seu ponto fosse imutável, tirando os setters e colocando a palavra rerservada final em cada atributo.

Enfim, a diferença básica é essa. Construtores devem passar os valores mínimos que uma classe precisa e os getteres and setters são o meio para buscar as informações contidas na classe. Porém, ressaltando novamente: getters and setters em demasia criam uma falsa sensação de OO. Mais sobre isso no link abaixo:

http://blog.caelum.com.br/2006/09/14/nao-aprender-oo-getters-e-setters/

Daniels,
obrigado pela resposta. Foi muito esclarecedora.
Agradeço a todos pelas respostas, mas acho que vou entender mesmo utilizando e programando bastante para amadurecer as idéias na minha cabeça…

Obrigado,

1 [ ] a todos…