Como atribuir informações digitadas pelo usuário diretamente no método construtor?

Olá, sou iniciante em POO e estou com uma dificuldade. Já peço perdão pelo texto longo que precisei escrever para explicar o problema. Tentei remover as redundâncias, mas me pareceu melhor com elas. Espero que dê para entender :wink:

Antes de ler o problema, veja como é a estrutura do meu projeto:

Tem uma classe principal chamada “ProjetoCanideo”, na qual fica o método “main”. Tem uma classe “raiz” chamada “Canideo” que tem 3 atributos privados com seus respectivos métodos “Getter” e “Setter” e um construtor que recebe aqueles 3 atributos. Tem também uma subclasse chamada “Cachorro”, que estende “Canideo”, que tem 5 atributos privados, também com seus respectivos métodos “Getter” e “Setter” e também um construtor que recebe aqueles 5 atributos. As classes “Canideo” e “Cachorro” também possuem o método “toString”, sendo que a subclasse concatena os atributos da superclasse usando a palavra “super”.

Problema:

Eu criei um objeto “Scanner” para receber dados do usuário e instanciei a classe “Cachorro” que receberá esses dados, mas tive que desativar os construtores das classes “Cachorro” e “Canideo” para fazer funcionar, isso porque preciso receber um dado por vez já que preciso mostrar mensagens, uma por vez, solicitando os dados. Foi necessário desativar os construtores porque ao instanciar uma classe que tem um construtor que recebe parâmetros, fico obrigado a informar todos eles no momento que crio o objeto. Eu poderia usar variáveis auxiliares na classe principal, mas acho que se eu fizer isso, vai perder um pouco a graça do encapsulamento. Obs.: Estou desconsiderando a “sobrecarga” do método construtor, que poderia criar ali junto um outro método construtor que não recebe parâmetros, porque acho que não se aplicaria para este caso.

Como uma solução mais elegante do que usar variáveis auxiliares na classe principal, eu estou usando os métodos “Setter” da classe “Cachorro”, e os herdados, para atribuir os dados recebidos para suas variáveis privadas, mas o meu desejo é de coletar os dados informados pelo usuário diretamente para os parâmetros do construtor da classe “Cachorro”, construtor esse que precisaria estar ativo, de maneira que eu não precise usar esses métodos “Setter” um por um.

Se fosse só para atribuir, não seria problema, eu poderia reativar os construtores e bastaria colocar o objeto de “Scanner” com o método “nextLine()” para cada uma das posições dos parâmetros do construtor, mas eu quero, como eu falei antes, mostrar mensagens solicitando dados do usuário usando o “print”, mas não tem como colocar o “print” junto com o “nextLine()” na posição do parâmetro, ou seja, dentro do chamamento do construtor.

Isso me obriga a fazer as coletas separadamente, como por exemplo, um “print” pedindo o nome e em seguida o “nextLine()” com o método “Setter” dentro para coletar o nome, além de que fico obrigado, como já falei, a desativar os construtores para conseguir instanciar a classe “Cachorro” sem passar parâmetros no construtor para poder usar esses métodos “Setter” ou qualquer outro método dela.

Será se tem como fazer o que eu quero?

Como este é um projeto apenas para aprendizado, estou disponibilizando o código fonte feito em IntelliJ para vocês analisarem. Como sou novo usuário, não pude subir o arquivo diretamente aqui, então coloquei na minha conta do OneDrive: https://1drv.ms/u/s!AlX3C7qG4wUDd8RGmTqsoqXujNc?e=QHhId6

Se você chegou até aqui, PARABÉNS e OBRIGADO!!! Você é uma pessoa com muita paciência hehe

Eu li que você não quer usar variáveis auxiliares, mas no seu caso é impossível fazer isso (ou talvez eu não tenha entendido o quê você quis dizer com isso).

De qualquer forma, a solução pra esse problema é usar variáveis para armazenar os valores digitados pelo usuário e depois usá-las como argumentos no construtor, simples.

Opa. Obrigado por responder.

De qualquer forma, a solução pra esse problema é usar variáveis para armazenar os valores digitados pelo usuário e depois usá-las como argumentos no construtor, simples.

Pois é, eu fiz isso, usei variáveis auxiliares, é o único jeito de fazer as coletas mostrando as mensagens antes e mantendo os construtores, mas como sou meio novo nisso, imaginei que poderia ter alguma outra forma em que eu pudesse não usar as variáveis auxiliares ou evitar o uso direto dos métodos “setter”.

Não coloque links. A maior parte das pessoas não vai acessar, por questões de segurança. Simplesmente copie e cole o código aqui, usando o botão de formatar o código.

Cachorro cachorrinho = new Cachorro(JOptionPane.showInputDialog("Nome do animal"));

Edit: o problema é que se o usuário cancelar a janela de coleta de dados, o programa vai gerar uma exceção, que precisará ser tratada.

Eu não li tudo. Tente ser mais objetivo nas próximas perguntas, se você desejar que mais pessoas leiam.

Na maior parte dos casos há mais de uma opção para fazer as coisas, em programação. Não necessariamente são as melhores. Procure estudar sobre “padrões de projeto”.

Se vc esta estudando Poo deve conheçer os construtores swing vc pode usar por exemplo uma caixa de texto e um botão para enviar os dados e no codigo estabeleçer
Objeto X = new Objeto();
X.setNome(“caixaDeTexto”)

Olá, amigo. Obrigado por responder.
Pois é, me ocorreu que o pessoal poderia ficar meio desconfiado mesmo, vou evitar colocar links então. Eu até tinha pensado em colar o código, vi outras pessoas fazendo isso em outras perguntas. Só não fiz porque eram três classes longas, aí achei que poderia ficar confuso.

@Fefo80
Cachorro cachorrinho = new Cachorro(JOptionPane.showInputDialog(“Nome do animal”));

Essa é um solução que pode funcionar, eu nem tinha pensado em usar essas janelas prontas. Vou tentar fazer.

@Fefo80
Eu não li tudo. Tente ser mais objetivo nas próximas perguntas, se você desejar que mais pessoas leiam.

:sweat_smile: É legal esse tipo de feedback. Vou tentar ser mais sintético nas próximas.

@Fefo80
Na maior parte dos casos há mais de uma opção para fazer as coisas, em programação. Não necessariamente são as melhores. Procure estudar sobre “padrões de projeto”.

Obrigado pela dica, vou pesquisar depois.

@Joao_Pedro_Martins
Se vc esta estudando Poo deve conheçer os construtores swing vc pode usar por exemplo uma caixa de texto e um botão para enviar os dados e no codigo estabeleçer

Na verdade eu estou tentando evitar mexer com interfaces gráficas, quero mais interação via terminal mesmo, porque quero aprender Java mais para servidor. Talvez eu até estude um pouco de interfaces gráficas, mas seria pra desenvolvimento mobile com o Android Studio. O @Fefo80 até deu a dica das janelas de diálogo que até posso considerar, mas Swing ou JavaFX melhor nem mexer.

Swing é mais antigo então tem mais material de estudo se vc esta começando, usa swing, no momento q vc tiver q enviar varios dados pro banco vc vai precisar mecher com interface o joption é bom mas vc deveria usar ele apenas pra soluçoes rapidas como erros ou opções de sim ou não.

Aprenda JavaFX se quiser mesmo ir para desktop. Swing está saindo de linha.

@Joao_Pedro_Martins
Swing é mais antigo então tem mais material de estudo se vc esta começando, usa swing, no momento q vc tiver q enviar varios dados pro banco vc vai precisar mecher com interface o joption é bom mas vc deveria usar ele apenas pra soluçoes rapidas como erros ou opções de sim ou não.

Pra ser sincero estou um pouco resistente com relação ao Swing porque pesquisei recentemente sobre ele e sobre o JavaFX e me pareceu que o Swing está meio em desuso por causa da tendência criada pela Web e mobile. O JavaFX me pareceu mais promissor porque foi desenvolvido pensando em web e talvez até em mobile, mas está parecendo que está meio devagar também.

Eu pesquisei esses tempos e pareceu que o JavaFX está meio abandonado. Posso estar enganado, mas parece que o número de versão não está mudando. Vou pesquisar melhor depois.

Eu não conheço as demandas do mercado, vocês sabem melhor que eu, sem dúvida, mas eu estou querendo Java mesmo para backend, em puro texto, mas não sei se é assim que o mercado trabalha.

O que tu queres parece-me que é “simplesmente” isto:

public class Main {

    private static Scanner s = new Scanner(System.in);

    public static void main(String[] args) {
        Exemplo ex = new Exemplo(leInput("Introduza campo1:"), leInput("Introduza campo2:"));
        System.out.println("Criada classe " + ex);
    }

    private static String leInput(String prompt){
        System.out.println(prompt);
        return s.nextLine();
    }
}

class Exemplo{
    private String campo1;
    private String campo2;

    public Exemplo (String campo1, String campo2){
        this.campo1 = campo1;
        this.campo2 = campo2;
    }

    @Override
    public String toString() {
        return "Exemplo{" +
                "campo1='" + campo1 + '\'' +
                ", campo2='" + campo2 + '\'' +
                '}';
    }
}

Mas não há que ter medo de criar as variáveis auxiliares quando necessárias…

Nossa, cara! É exatamente isso que eu queria. Muito interessante esse jeito que você fez, criou um método auxiliar bem simples que mostra a mensagem e recebe o valor. Muito interessante!

Muito obrigado!

Acabei de testar aqui, ficou absolutamente perfeito!
Mais uma vez, obrigado!:grinning: