Como consertar esses erro em construtores?

[code]public class Pessoa {

 public Pessoa (String login, String senha)
 this.setLogin(login);
 this.setSenha(senha);

}[/code]

qual erro no caso?? não identifico de fato…

Faltam as {} do construtor. E se isso é toda a classe, faltam os métodos setLogin e setSenha.

public class Pessoa {
private String login;
private String senha;

 public Pessoa (String login, String senha)  { 
 this.setLogin(login);  
 this.setSenha(senha);  

}

//metodos get e sets.

}

[quote=alexmonassa]

[code]public class Pessoa {
private String login;
private String senha;

 public Pessoa (String login, String senha)  { 
 this.setLogin(login);  
 this.setSenha(senha);  

}

//metodos get e sets.

}[/code] [/quote]

Chamar métodos sobrecarregáveis é um exemplo de coisa que não se deve fazer em construtores. Se for fazer assim, certifique-se que os sets são final, o que a classe toda é final.

Também não vi erro nenhum.

[quote=ViniGodoy][quote=alexmonassa]

[code]public class Pessoa {
private String login;
private String senha;

 public Pessoa (String login, String senha)  { 
 this.setLogin(login);  
 this.setSenha(senha);  

}

//metodos get e sets.

}[/code] [/quote]

Chamar métodos sobrecarregáveis é um exemplo de coisa que não se deve fazer em construtores. Se for fazer assim, certifique-se que os sets são final, o que a classe toda é final.[/quote]

ah nem tinha visto essa gambiarra . E me fale dessa regra de não poder fazer chamada de métodos sobrecarregados em construtores.

O problema é que o construtor ocorre no momento em que o objeto está sendo criado. A criação das classes ocorre a partir da classe pai em direção as filhas. Então, você pode estar chamando um método numa parte da classe que sequer foi construída ainda. Isso gera um dos poucos comportamentos indefinidos da linguagem Java.

Perfeito!!! Capitei vossa mensagem , estimado mestre lOL

Também não vi erro nenhum.[/quote]

É na verdade, era só a chaves ( { } ) (que faltava) , quem sabe…

Como diria o Chaves, isso isso isso… :slight_smile:

Também não vi erro nenhum.[/quote]

É na verdade, era só a chaves ( { } ) (que faltava) , quem sabe…

Como diria o Chaves, isso isso isso… :)[/quote]

Não achei que isso fosse erro, já que ele não postou código de método nenhum. Eu hein.

mas pode haver casos q isso seja imprescindível.
por exemplo:

no construtor eu chamo um metodo q é responsável por instanciar determinado objeto.
porém quem define é somente a especializada.

como faria?

mas pode haver casos q isso seja imprescindível.
por exemplo:

no construtor eu chamo um metodo q é responsável por instanciar determinado objeto.
porém quem define é somente a especializada.

como faria?[/quote]

Deixe a classe filha instanciar e guardar a referência desse objeto. Ou use lazy-loading. Ou, melhor ainda, use composição.

Não dará problema se esse método não usar NENHUM atributo. Mas tem que tomar cuidado pois é o tipo da coisa que, se usada errada, vai gerar um erro que leva milênios para corrigir.

Ironicamente, eu descobri isso numa situação parecida com a que você descreveu. Eu tinha uma tela padrão, que continua os botões básicos de salvar, carregar, etc. E no centro, haveria nessa tela um painel, que variaria de classe filha para classe filha. No construtor do pai, eu chamava o método createPanel() que era abstrato, e seria definido na filha. Soa bastante plausível, não?

add(createPanel());

Porém, o que acontecia:

  • O método createPanel era acionado;
  • Todas as criações de atributos da classe filha ocorriam no momento do acionamento do método. Ou seja, os atributos da classe eram inicializados com seus valores padrão e o código de createPanel rodava;
  • Quando o construtor rodava e ia para a classe filha, os atributos já criados eram re-inicializados pela VM. Eu acaba com um monte de labels que estavam na tela, mas não eram as mesmas labels dos atributos, já que nos atributos estavam as que foram criadas novamente.

Ainda bem que descobri o que estava acontecendo a tempo, já estava quase virando veterinário, indo morar no campo e deixando a área de informática para pessoas mais competentes.

O comportamento em VMs Linux era diferente - e um tanto mais catastrófico. Os atributos padrão não eram inicializados na chamada e dava NullPointerException na hora de adiciona-los ao painel.

Resolvemos o problema fazendo com que a classe da tela recebesse esse painel por parâmetro, após construída. Ou seja, usamos composição e deixamos a hierarquia nos paineis e não nos frames. O resultado acabou bem melhor do que nossa idéia inicial (embora um pouco mais trabalhoso).

mt obrigado ViniGodoy.

entendi sua colocação, embora não compreendi o pq de ser assim. dá impressão até de não deveria ser.

vou tentar emular essa situação aki, pois apesar de não programar em java, vira e mexe e preciso de alguma coisa.
e esse tipo de situação, q me parece específico da plataforma, é dakelas q devemos anotar no “carderninho de ouro”.

O problema central está no fato do construtor, como o nome indica, estar criando o objeto. A criação segue uma ordem específica, de cima para baixo. Então, quando você chama um método no filho, está chamando um código de um pedaço do objeto que não existe ainda.

Lembre-se, o construtor é o primeiro código executado para criar um objeto. É ali que tudo é inicializado. Um método virtual burla a ordem normal das coisas e aí vem o comportamento indefinido.

Claro, você escapa desse comportamento se o método chamado não usar nenhum atributo da classe (ou seja, nada que ainda não foi inicializado). Mas como garantir isso 100% das vezes?

Tipo isso?

public abstract class Teste1 {
	
	public Teste1() {
		initialize();
	}
	
	protected abstract void initialize();
	public  abstract void show();	
}

[code]public class Teste2 extends Teste1 {
private int a = 1;
private int[] b = new int[20];

@Override
protected void initialize() {
	a++;
	System.out.println(a);
	for (int i : b) {
		System.out.println(i);			
	} 
}

@Override
public void show() {
	System.out.println(a);		
}

}
[/code]

[code]public class Main {

public static void main(String[] args) {
	Teste1 t = new Teste2();
	t.show();
}

}
[/code]

mt obrigado pela dica!!