essa é uma dúvida longa, mas que talvez a resposta da primeira parte sirva pra resolver as demais. primeira parte:
porque esse código:[code]class Teste{
public static void main(String[] args){
for (int i=0; i<3; i++){
System.out.println(i);
}
}
}[/code]compila e esse, cuja única diferença é que ele não é public:class Teste{
for (int i=0; i<3; i++){
System.out.println(i);
}
} não compila?
Ele dá o erro “illegal start of type”, logo no for, e mais um monte de erros de sintaxe.
segunda parte:
Esse erro ocorreu quando eu tentava aprender arrays. Tenho uma classe “Casa”, que tem três instâncias da classe “Porta”. Minha idéia era criar uma array de “Porta” dentro de “Casa”. Eu uso uma terceira classe (“TestaCasa”) pra fazer as alterações ao longo da “Casa”. Eu não gostaria de criar as instâncias de “Porta” dentro de “TestaCasa”, porque eu posso precisar, no futuro, de algum comando desse estilo, uma classe que crie uma array de comprimento pré-determinado, então, como faria? Atualmente, meu código da classe “Casa” é o seguinte:
[code]class Casa{
String cor;
Porta[] portas = new Porta[3];
//esse código abaixo foi o que gerou a primeira dúvida
/* for (int i=0; i<3; i++){
portas[i]=new Porta();
} */
//eu usava esse código abaixo antes de começar com arrays
/* int i=0;
i= (porta1.aberta==true) ? i+1: i;
i= (porta2.aberta==true) ? i+1: i;
i= (porta3.aberta==true) ? i+1: i;
System.out.println("portas abertas: "+i); */
}
void mostra(){
System.out.println("cor da casa: "+cor);
for (int i=0; i<3; i++){
System.out.println("cor da porta “+(i+1)+”: "+portas[i].cor);
}
}
}[/code]Então, se não ficar na cara qual é o erro ao resolver a primeira parte, como devo criar a array de “Porta”?
na verdade… seus dois problemas sao originados de um so… é bem simples na verdade… e é muito comum acontecer no inicio… o que esta acontecendo é que voce esta colocando o seu for ‘jogado’ jogado dentro da classe… ou seja ele nao esta dentro de um metodo…
na primeira situacao…
o primeiro exemplo de codigo …
class Teste{
public static void main(String[] args){
for (int i=0; i<3; i++){ // funciona por que esta dentro do metodo main
System.out.println(i);
}
}
}
no segundo exemplo de codigo
class Teste{
for (int i=0; i<3; i++){ // nao funciona por que nao tem metodo para executar.. o codigo esta solto
System.out.println(i);
}
}
agora respondendo sua segunda duvida
nao esta funcionando pelo mesmo motivo que eu falei acima… a maneira correta de vc iniciar o seu vetor… é colocando seu for dentro do construtor da classe
class Casa{
String cor;
Porta[] portas = new Porta[3];
Public Casa(){// este e o construtor da casa... que vai iniciar seu vetor
for (int i=0; i<3; i++){ // agora sim o for funciona
portas[i]=new Porta();
}
}
}
a classe nunca é executada, ele só serve pra encapsular um apanhado de dados e ações, ou como é nomeado em Java, atributos e métodos
consequentemente, para que haja uma execução de código, ela deve estar dentro de um método para que possa ser acionada.
o máximo que uma classe processa fora de métodos é a inicialização dos atributos fora do construtor, mas muitas vezes é melhor fazer a inicialização dentro do construtor
class Classe {
private int i = 0; // inicializa
private void metodo() {
}
}
Obrigado! Eu tinha esquecido que “main” é um método (ainda não fixei esses “cabeçalhos” na cabeça).
Isso explica o erro.
Uma classe “public” significa que ela sempre será executada?
Ainda não cheguei na parte que explica o que é “public”…
Outra dúvida: caso eu NÃO quisesse um número pré-determinado de "Porta"s, eu criaria a array de "Porta"s na classe (main) “TestaCasa”? Tipo:
class TestaCasa{
public static void main (String[] args){
Casa minhaCasa = new Casa();
Porta[] portas = new Porta[5];
for (int i=0; i<5; i++){
minhaCasa.portas[i]=new Porta();
}
}
}
Tenho quase certeza que isso não vai funcionar, mas acho que deu pra entender essa nova dúvida: quero também criar uma array genérica de "Porta"s dentro da “Casa” minhaCasa, mas fazendo isso a partir do método main.
public, protected e private não são códigos, são indicadores de visibilidade (alteram quais outras classes podem acessar os atributos e métodos daquela classe)
se quiser fazer algo quando a classe é iniciada, utilize um método construtor:
public class Classe {
public Classe() { // não possui retorno (nem void), e possui exatamente o mesmo nome que a classe. pode ter parâmetros
// código de quando inicializa a classe
}
lembrando que o static main não inicializa a classe, pois é um método estático. Para usar a classe nela mesmo faça:public class Classe {
public Classe(){
}
public metodo(){
}
public static void main (String args[]) {
Classe c = new Classe(); // cria um objeto (c) do tipo Classe. A palavra "new" ativa o método construtor
c.metodo(); // ativa o método
}
}
ficando um pouco mais claro na sua dúvida, quanto aos arrays:
public class Casa {
private Porta[] portas;
public Casa(int qtdPortas) { // construtor
porta = new Porta[qtdPortas];
}
public static void main (String args[]) {
Casa c = new Casa(5); // tem 5 portas
}
}
Esse seu último código DEVE ter algum problema, olha só: eu quero uma variável pra determinar em qual “Porta” estou mexendo. Essa variável é “portas” (minúsculo e no plural).
portas[0];
portas[1];
etc.
Talvez você quizesse dizer algo como:
[quote]public class Casa {
private Porta[] portas;
public Casa(int qtdPortas) { // construtor
portas[qtdPortas] = new Porta;
}
public static void main (String args[]) {
Casa c = new Casa(5); // tem 5 portas
}
} [/quote]Certo ou errado, isso está um pouco complicado demais pra mim, por enquanto. Vamos ao teste que eu deveria ter feito antes de responder.
minha classe Casa, agora, está assim:
[code]class Casa{
String cor;
Porta[] portas = new Porta[3];
public Casa(){
for (int i=0; i<3; i++){
portas[i]=new Porta();
}
}
void pinta(String s){
if (this.cor==s){
System.out.println("cor igual");
}
else{
this.cor=s;
System.out.println("nova cor:"+s);
}
}
void portasAbertas(){
int j = 0;
for (int i=0; i<3; i++){
portas[i]=new Porta();
j=(portas[i].aberta==true) ? j+1 : j;
}
System.out.println("portas abertas: "+j);
}
void mostra(){
// System.out.println("cor da casa: "+cor+"\n cor da porta1: "+portas[0].cor+"\n cor da porta2: "+portas[1].cor+"\n cor da porta3: "+portas[2].cor);
System.out.println("cor da casa: "+cor);
for (int i=0; i<3; i++){
System.out.println("cor da porta "+(i+1)+": "+portas[i].cor);
}
}
}[/code]Ela compila, numa boa, e a chamada dos métodos dela rodam direitinho. Mas ao chamar os métodos da classe Porta, o comportamento é estranho. Deixa eu colar a classe Porta, aqui, pra explicar melhor:
[code]class TestaCasa{
public static void main(String[] args){
Casa minhaCasa=new Casa();
minhaCasa.cor=“amarelo”;
minhaCasa.portas[0].cor="verde";
minhaCasa.portas[1].cor="verde";
minhaCasa.portas[2].cor="verde";
//mostra a situação inicial
System.out.println("situação inicial:");
minhaCasa.mostra();
minhaCasa.portasAbertas();
//pinta tudo
minhaCasa.portas[0].pinta("vermelho");
minhaCasa.portas[1].pinta("verde");
minhaCasa.portas[2].pinta("azul");
minhaCasa.pinta("cinza");
//abre/fecha algumas portas
minhaCasa.portas[0].abre();
minhaCasa.portas[1].fecha();
minhaCasa.portas[2].abre();
//mostra a situação final
System.out.println("situação final:");
minhaCasa.mostra();
minhaCasa.portasAbertas();
}
}[/code]À primeira vista, ele roda bem e até pinta as portas das cores certas. Mas a porta que é pintada de cor repetida não mostra a string "cor igual", como deveria (mostra "nova cor: verde") e, ao rodar o número de portas abertas, o resultado é zero, nas duas vezes.
é, de fato, errei o nome da variável no meu exemplo…
no seu Casa::portasAbertas() você tá reinicializando as portas no for:
for (int i = 0; i < 3; i++){
portas[i] = new Porta(); // reaplica o construtor, que deixa o boolean com valor default, que é false
...
}
nas String, tenta ver se fica melhor com o .equals()
if (s.equals(cor))
o equals() compara o texto da String, o == compara em qual espaço da memória a string tá alocada
Deu na mesma… Estranho, quando eu usava os códigos sem usar arrays, funcionava redondinho.
E quanto ao método portasAbertas? Ele DEVERIA resultar em duas portas abertas, no final.
Sinto como se a cada método que eu chamasse, ele usasse uma nova array, como se as informações anteriores estivessem sendo ignoradas.
[quote=saim]Deu na mesma… Estranho, quando eu usava os códigos sem usar arrays, funcionava redondinho.
E quanto ao método portasAbertas? Ele DEVERIA resultar em duas portas abertas, no final.
Sinto como se a cada método que eu chamasse, ele usasse uma nova array, como se as informações anteriores estivessem sendo ignoradas.[/quote]
e ele está refazendo o array a cada chamada, na linha que já indiquei:
for (int i = 0; i < 3; i++){
portas[i] = new Porta(); // refaz o objeto do zero, apagando tudo que ele tinha antes
Hm… A CADA vez que eu chamo a instância minhaCasa a array é re-criada? Isso é mau.
Tem como eu criar a array no instante em que eu crio a instância e não criar mais?
Edit: Ah, você quis dizer dentro do método portasAbertas!!! Passou batido…
Tirei a linha “portas[i]=new Porta();”, mas nada mudou…
Nesse meio-tempo, vou tentando criar a array a partir de TestaCasa, mesmo. Volto aqui pra avisar se consegui (ou perguntar como faz, se não conseguir)…
Edit2: Ih, lascou, agora nem compila mais… ele fica procurando a variável portas dentro de Casa, e lá, a variável não foi iniciada. O lance é criar a array na Casa, mesmo…
bump (não consegui encontrar, nas regras, quanto tempo tenho que esperar pra poder dar um bump)…
Ainda não consegui manter as portas abertas.
Como eu deveria fazer?