Problema com método menu

Criei uma classe Porta com alguns métodos que abre, fecha, tranca, destranca e exibe o status da porta.
Minha classe principal “TestePorta” tem um método chamado menu fazendo as respectivas chamadas dos métodos da classe Porta.

O problema é que ao executar o programa ele chama os métodos, porém não está salvando.
Exemplo: A porta inicia aberta, mando fechar, ela fecha. Se escolho verificar o status da porta ele retorna como porta aberta.
Segue o código:

public class Porta {
private boolean portaAberta = true;
private boolean tracarPorta=false;

public void abrirPorta(){
    if(portaAberta==false && tracarPorta == true)
        System.out.println("A porta está trancada e não pode ser aberta.\n");

    if(portaAberta ==true)
        System.out.println("A porta já está aberta.\n");

    if(portaAberta==false && tracarPorta==false) {
        portaAberta = true;
        System.out.println("A porta foi aberta.\n");
        }
    }

public void fecharPorta(){
    if(portaAberta ==false)
        System.out.println("A porta já está fechada.\n");
    else {
        portaAberta = false;
        System.out.println("A porta foi fechada.\n");
    }
}

public void trancarPorta(){
    if(portaAberta == false && tracarPorta == true)
        System.out.println("A porta já está trancada.\n");
    if(portaAberta == false && tracarPorta == false){
        tracarPorta = true;
        System.out.println("A porta foi trancada.\n");
    }
    if(portaAberta == true && tracarPorta == false){
        portaAberta = false;
        tracarPorta = true;
        System.out.println("A porta foi fechada e trancada.\n");
    }
}

public void destrancarPorta(){
    if(tracarPorta==true){
        tracarPorta = false;
        System.out.println("A porta foi destrancada.\n");
    }else
        System.out.println("A porta já esta destrancada.\n");
}

public void estadoPorta(){
    if(portaAberta == true && tracarPorta == false)
        System.out.println("A porta está aberta.\n");
    if(portaAberta == false && tracarPorta == false)
        System.out.println("A porta está fechada e destrancada.\n");
    if(portaAberta == false && tracarPorta == true)
        System.out.println("A porta está fechada e trancada.\n");
}

}//Fim da classe Porta

public class TestePorta {
public static void main (String[] args){
TestePorta.menu();
}//Fim da classe main

//Método de menu para fazer as chamadas dos métodos da classe Porta
public static void menu(){
    Porta porta = new Porta();//Declarando a variável de instância porta
    Scanner entrada = new Scanner(System.in);
    int opcao;

    System.out.println("0-Sair");
    System.out.println("1-Abrir porta");
    System.out.println("2-Fechar porta");
    System.out.println("3-Trancar porta");
    System.out.println("4-Destrancar porta");
    System.out.println("5-Estado da porta\n");
    opcao = entrada.nextInt();

    //Switch para avaliar a opcao digitada e chamar o respectivo método descrito no menu
    switch(opcao){
        case 0:
            System.out.println("Encerrando o programa.");
            break;
        case 1:
            porta.abrirPorta();
            menu();
        case 2:
            porta.fecharPorta();
            menu();
        case 3:
            porta.trancarPorta();
            menu();
        case 4:
            porta.destrancarPorta();
            menu();
        case 5:
            porta.estadoPorta();
            menu();
        default:
            System.out.println("Número inválido.\n");
            menu();
        }//Fim do switch
    }//Fim do método menu
}//Fim da classe TestePorta

Seu código não tem um laço de repetição para que o seu código continue em execução, permitindo que o mesmo possa armazenar os valores nas variáveis e utilizá-los.
Sempre que você executar ele pegará os valores padrão de inicialização, fará o que você informar uma única vez e encerrará, por isso seu código não funciona!

Você esqueceu de por break na maioria dos seus case e você está recursivamente chamando o método menu() e consequentemente criando uma nova Porta.

Mas não chame o método menu() nesses case.
Você precisa fazer um laço e não usar recursividade.

Renomeie a variável tracarPorta para portaTrancada.

E não teste dessa forma:

if (condicao == true) {
}

if (condicao == false) {
}

Teste assim:

if (condicao) {
}

if (!condicao) {
}

Isso já vai deixar seu código mais legível.

O código continua em execução pois ele usou recursividade, mas não está certo para esse cenário. Uma hora a pilha de memória estoura.
Ele tem que tirar as chamadas recursivas e fazer um laço.

1 curtida

Exemplo de como você poderia fazer para que seu código fique mais legível e mais simples!

public class Porta {

private boolean portaAberta; //True -> Porta Aberta | False -> Porta Fechada
private boolean portaTrancada; //True -> Porta Trancada | False -> Porta Destrancada

public Porta() {
    this.portaAberta = true; //Aberta
    this.portaTrancada = false; //Destrancada
}

public void abrirPorta() {
    if (portaTrancada) {
        System.out.println("Destranque a porta para poder abri-lá!\n");
        return;
    }
    
    if (portaAberta) {
        System.out.println("A porta já está aberta!\n");
        return;
    }
    
    this.portaAberta = true;
    System.out.println("A porta foi aberta!\n");
}

public void fecharPorta() {
    if (!portaAberta) {
        System.out.println("A porta já está fechada!\n");
        return;
    }
    
    this.portaAberta = false;
    System.out.println("A porta foi fechada!\n");
}

public void destrancarPorta() {
    if (portaAberta) {
        System.out.println("Para destrancar a porta e necessário que ela esteja fechada e trancada!\n");
        return;
    }
    
    if (!portaTrancada) {
        System.out.println("A porta já está destrancada!\n");
        return;
    }
    
    this.portaTrancada = false;
    System.out.println("A porta foi destrancada!\n");
}

public void trancarPorta() {
    if (portaAberta) {
        System.out.println("Para trancar a porta e necessário fechá-la primeiro!\n");
        return;
    }
    
    if (portaTrancada) {
        System.out.println("A porta já está trancada!\n");
        return;
    }
    
    this.portaTrancada = true;
    System.out.println("A porta foi trancada!\n");
}

public void status() {
    String situacaoPorta = this.portaAberta ? "Aberta" : "Fechada";
    String situacaoTranca = this.portaTrancada ? "Trancada\n" : "Destrancada\n";
    
    System.out.println("A porta está ".concat(situacaoPorta).concat(" e ").concat(situacaoTranca));                
}

public static void main(String ... args) {
    boolean sair = false;
    Integer opcao;
    Porta porta = new Porta();
    Scanner resposta = new Scanner(System.in);
    
    while (!sair) {            
        System.out.println("0-Sair");
        System.out.println("1-Abrir porta");
        System.out.println("2-Fechar porta");
        System.out.println("3-Trancar porta");
        System.out.println("4-Destrancar porta");
        System.out.println("5-Estado da porta\n");
        
        opcao = resposta.nextInt();
        
        switch (opcao) {
            case 0:
                sair = true;
                break;
            case 1:
                porta.abrirPorta();
                break;
            case 2:
                porta.fecharPorta();
                break;
            case 3:
                porta.trancarPorta();
                break;
            case 4:
                porta.destrancarPorta();
                break;
            case 5:
                porta.status();
                break;                    
            default:
                System.out.println("O valor informado está fora do intervalo válido!\n");
                break;
        }
    }
}
}
1 curtida

Jonathan_Medeiros e staroski

Muito obrigado pelas respostas e dicas que vocês deram, graças a isso consegui entender o motivo pelo qual não estava funcionando corretamente o código. Agora deu certo!

E já aproveitei e simplifiquei o código conforme vocês sugeriram e realmente ficou beeem melhor.
Obrigado pela ajuda!