Instanciar diferentes Classes em um mesmo comando

Pessoal,

dúvida: é possível que a instrução para instanciar não tenha a Classe/Método fixa? Vejam exemplo abaixo:

. Situação Normal. A Classe e Método são fixos. Sempre sera ClasseTeste1 e metodoTeste1.

     ClasseTeste1 classeteste = new ClasseTeste1();
     classeteste.metodoTeste1();¨

. Situação que eu quero saber se é possivel. A Classe e o Método são variáveis:

    String variávelClasse, variávelMetodo;

    if (parametro == 1) {
       variávelClasse  = "ClasseTeste1";
       variávelMetodo = "metodoTeste1";
    }
    else {
       variávelClasse  = "ClasseTeste2";
       variávelMetodo = "metodoTeste2";
    }

    variávelClasse classeteste = new variávelClasse();
    classeteste.variávelMetodo();

O que eu quero é poder mudar a Classe/Método dinâmicamente.

Grato.

Vi que você se deu ao trabalho de colocar os acentos em “variável”, :slight_smile: pena que é uma má pratica colocar acentos em nomes de coisas no código :wink:

Agora, sobre sua pergunta, você pode mudar o Objeto que uma variável de referência está referenciando contando que ela não tenha sido marcada como final . Não dá pra mudar os métodos de um Objeto em tempo de execução em Java (talvez até de em Javascript, não tenho certeza).

Você pode usar o Padrão de Projetos Strategy se precisar fazer isso.

Para mudar o Objeto (a instância) que uma variável Referencia, você pode fazer algo assim:

Veiculo variavelDeReferencia;
if (...) { variavelDeReferencia = new Carro(); } else { variavelDeReferencia = new Moto(); }
//Isso só compila se as Classes "Carro" e "Moto" extenderem a Classe "Veiculo".
//Também compila se "Veiculo" for uma Interface que "Carro" e "Moto" implementam

O Padrão Strategy não te permite mudar os métodos de um Objeto em Tempo de Execução, mas permite alterar em Tempo de Execução o código que eles executam, mudando o comportamento deles. Exemplo:

public class Carro extends Veiculo {
    private Buzina buzina; //Essa é nossa "Estratégia"
    public void setBuzina(Buzina novaBuzina) {buzina = novaBuzina;} //permite alterar a "Estratégia" em Tempo de Execução
    public void buzinar() {buzina.emitirSom();} //Usamos a "Estratégia" atual
}

public class BuzinaNormal extends Buzina {//1ª Estratégia disponível
    public void emitirSom() { System.out.println("Biiii");}
}

public class BuzinaEngracada extends Buzina {//2ª Estratégia disponível
    public void emitirSom() { System.out.println("Biiii Biribi bibi");}
}

Usa-se assim:

Carro carro = new Carro();
carro.setBuzina(new BuzinaNormal()); //Definimos a Estratégia em Tempo de Execução
carro.buzinar(); //Usamos a Estratégia Atual, o carro faz "Biiii"
carro.setBuzina(new BuzinaEngracada()); //Redefinimos a Estratégia em Tempo de Execução!
carro.buzinar(); //Usamos a Nova Estratégia, o carro faz "Biiii Biribi bibi"
1 curtida

Douglas,

valeu pelo toque sobre o uso de acentos. Grato tb pela análise do uso de variável no instanciamento. Na verdade o que
eu queria saber é se seria possivel criar uma Classe como uma API. Essa Classe (API) teria a função de Abrir uma Janela com as opções e usando o ActionListener. O Método actionPerformed (obrigatório) que tem a função de detectar qual botão (ok ou cancela) foi pressionado chamaria de volta (retornaria) a Classe/Método chamador informando o botão pressionado. Minha ideia seria ter apenas uma Classe/Metodo com esta função atendendo a todo o Projeto (são varios os pontos em que precisarei abrir uma janela com OK/Cancela). Entendo q eu evitaria a redundância.

Pensei nessa solução pois não conseguir fazer com que o Método actionPerformed retorna-se o botão pressionado. Tentei usá-lo sem o void (e com o return) mas a compilação não aceita.

Deixa ver se eu entendi:

  • Você tem varias Telas que tem Botões “Ok” e “Cancela”;
  • Ao clicar em um Botão “Ok” deve abrir uma Tela, ao clicar no “Cancela” deve abrir outra Tela;

Se é isso, eu pergunto:

  • Existe apenas uma TelaX que abre se qualquer botão “Ok” de qualquer Tela for clicado?
  • Existe apenas uma TelaY que abre se qualquer botão “Cancelar” de qualquer Tela for clicado?

Douglas,

quase isso. Exemplificando, imagine um projeto onde teremos 4 telas diferentes. Cada tela inclui dados em 4 DBs diferentes. Em cada uma dessas 4 telas, após a digitação dos dados e antes de inserir efetivamente na base de dados eu abrirei uma janela com as opções e . Minha ideia é ter uma única Classe/Método com a função
de abrir a Janela com os 2 botões, detectar qual botão foi pressionado (usando o ActionListener) e responder a Classe/Método chamador. Lembrando que quem chamou pode ser qualquer uma das 4 Classes/Métodos que inserem dados no DBs.

Então você vai abrir uma Janela com os Botões “OK” e “Cancelar” para o usuário decidir se quer ou não salvar os Dados Inseridos na Tela Anterior?

Douglas, o texto anterior ficou misturado. Ignore-o e considere o abaixo:

quase isso. Exemplificando, imagine um projeto onde teremos 4 telas diferentes. Cada tela inclui dados em 4 DBs diferentes. Em cada uma dessas 4 telas, após a digitação dos dados e antes de inserir efetivamente na base de dados eu abrirei uma janela com as opções e .
Minha ideia é ter uma única Classe/Método com a função de abrir a Janela com os 2 botões, detectar qual botão foi pressionado (usando o ActionListener) e responder a Classe/Método chamador. Lembrando que quem chamou pode ser qualquer uma das 4 Classes/Métodos que inserem dados nos DBs.

que opções?

Pra mim ainda parece que você quer fazer o que acabei de te perguntar

Douglas,

estou apanhando na coisa mais basica, que é escrever aqui. O texto, sei lá pq, tá ficando cortado. Mas, é isso mesmo. Quero abrir uma janela perguntando se o usuario quer inserir ou não. Como essa janela vai aparecer em varias partes do projeto eu queria ter um unico grupo de linhas de codigo com essa tarefa. Varias Classes/Metodos chamariam essa API e receberiam em resposta qual o botão foi pressionado.

O que você quer fazer é facilmente implementado com o JOptionPane, assim:

int escolhaDoUsuario = JOptionPane.showConfirmDialog(null, "Deseja Salvar Agora?", "Salvar Agora", JOptionPane.OK_CANCEL_OPTION);
if (escolhaDoUsuario == JOptionPane.OK_OPTION) {
	System.out.println("Salvando no BD...");
} else if (escolhaDoUsuario == JOptionPane.CANCEL_OPTION) {
	System.out.println("Edite os Dados Novamente!");
}
1 curtida

Entendo. É que eu estava buscando uma forma de tornar a API (a Classe/Método que mostra a Janela com as
opções OK ou Cancela) independente. Usando o JOptionPane a execução é “conversational”, ou seja, a execução
para (stop) aguardando a opção do usuário. Por outro lado, vi que usando a ActionListener na API, a Classe/Metodo chamadora continua executando logo após chamá-la, podendo, portanto, ser encerrada. Achei interessante um fluxo onde, enquanto o usuario não decide, nada está rodando, exceto a API com o ActionListener.