Em um sistema de banco tenho dois tipos de conta, Conta1 e Conta2.
O que difere uma de outra é simples, Conta2 pode ter saldo negativo.
O programa está algo assim:
Interface Conta
Conta1 implements Conta
Conta2 extends Conta1 implements Conta
ListaConta (Que é uma ArrayList do tipo Conta1)
Conta2 tem os mesmos atributos de Conta1.
O problema é o seguinte, cadastro na arraylist tanto conta1 como conta2, porém eu vou efetuar um saque, eu estou conseguindo ter saldo negativo no tipo de conta Conta1(que não era para poder ter). E fiz os métodos tanto em Conta1 e Conta2, por polimorfismo ele não deveria saber que “método” usar?
Dúvida
12 Respostas
Bom, vendo esse tópico, que não tem código nenhum pra exemplificar o que você está executando, a única coisa que posso responder é:
Sim!
por polimorfismo ele sabe qual o tipo do objeto real, e invoca o método do mesmo, independendo do tipo da variável.
Quando você vai pesquisar, vai até o google e digita “ajuda”? Ou procura por algum assunto específico como “problemas com polimorfismo”?
Portanto, ajude-se e nos ajude a te ajudar. Coloque títulos claros e seja objetivo (e não subjetivo) na descrição do problema).
O que eu esperava é que ele também fizesse isto por polimorfismo, porém não está fazendo. Erro meu?! Devo checar os métodos?!
Só pensei em polimorfismo no final do que eu estava digitando, pois nem eu ao certo sei o erro. Me desculpe. Se tiver como mudar o nome do tópico, ajudará a comunidade.
E como vc garante que em Conta1 o saldo nunca fica negativo? Dispara exceção?
Outra coisa. Ao postar tópicos, por favor, dê um título descritivo. O título “Dúvida” não ajuda em nada quem lê a lista de tópicos.
Tome cuidado com outro detalhe. Se Conta2 é um Conta1, então você criou tipos de Conta1 que podem sim ser negativos.
É plenamente possível fazer:
Conta1 c1 = new Conta2();
c1.setSaldo(-100);
Lembre-se também que Conta2 respode “true” para a pergunta se ela é um “instanceof Conta1”.
Se conta2 não “é um” tipo de conta1, então, não use herança. Crie duas classes diferentes e herde a interface.
Se quiser evitar duplicação de código, crie um AbstractConta para ser pai das duas.
Exatamente isto.
Eu garantia que em Conta1 não teria saldo negativo no método de saque dela. Entende? O saldo nunca poderia ser menor que zero.
O que eu fiz foi colocar um atributo “tipoDeConta”, então logo no início dos dois métodos saque eu dou um if(tipoDeConta == 1) em um e no outro if(tipoDeConta == 0). Fiz isto e consegui o que eu queria, ou seja, só entra naquele especifico método se o atributo (tipoDeConta) for correspondente. Entende?
Pode postar suas classes Conta, por favor?
Aliás, isso está cheirando mal. Seu método de saque não deveria testar pelo tipo de conta. Afinal, ele já está na classe de conta certa.
Deveria ser algo como:
public class Conta1 {
public void saque(int valor) {
if (saldo - valor < 0) {
throw new IllegalArgumentException("Não há dinheiro para realizar o saque.")
saldo -= valor;
}
}
public class Conta2 extends Conta1 {
public void saque(int valor) {
saldo -= valor;
}
}
Sem qualquer tipo de teste.
Aliás, isso está cheirando mal. Seu método de saque não deveria testar pelo tipo de conta. Afinal, ele já está na classe de conta certa.Opa, valeu pela força. Então, os meus métodos de saque são do tipo boolean, se há algum erro ele retorna false, irei postar os dois: De Conta1:Deveria ser algo como:
public class Conta1 { public void saque(int valor) { if (saldo - valor < 0) { throw new IllegalArgumentException("Não há dinheiro para realizar o saque.") saldo -= valor; } }public class Conta2 extends Conta1 { public void saque(int valor) { saldo -= valor; } }Sem qualquer tipo de teste.
public Boolean saque(ListaDeConta lista, String numero, double valor, Data dt) throws ContaIneException{
int pos = lista.pesquisaNumero(numero);
if (lista.pesquisaNumero(numero) != -1){
if(lista.get(pos).getTipoDeConta() == 0){
if (lista.get(pos).getSaldo() - valor >= 0){
lista.get(pos).setSaldo(lista.get(pos).getSaldo() - valor);
return true;
}
}
}
return false;
}
public Boolean saque(ListaDeConta lista, String numero, double valor, Data dt) throws ContaIneException{
int pos = lista.pesquisaNumero(numero);
if (lista.pesquisaNumero(numero) != -1){
if(lista.get(pos).getTipoDeConta() == 1){
if (lista.get(pos).getSaldo() >= 0 && lista.get(pos).getSaldo() - valor >= -1000){
if (lista.get(pos).getSaldo() - valor < 0){
lista.get(pos).setSaldo(lista.get(pos).getSaldo() - valor);
classAux[i] = new ContaAux(dt, numero);
size++;
return true;
}
lista.get(pos).setSaldo(lista.get(pos).getSaldo() - valor);
return true;
}
}
}
return false;
}
Não repare nos pog. Então, eu tive que colocar o if(tipoDeConta == 1) em um e no outro if(tipoDeConta == 0) para funcionar do jeito que eu gostaria..
Esse seu método está estranho.
O método saque deveria sacar da própria conta, não de uma lista de contas.
Me parece que vc está com programação estruturada na cabeça (pensando em funções e dados, e não em classes).
Esse seu método está estranho.
O método saque deveria sacar da própria conta, não de uma lista de contas.Me parece que vc está com programação estruturada na cabeça (pensando em funções e dados, e não em classes).
To começando a aprender agora. <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@14/assets/72x72/s.pngmiley.png?v=9" title=":smiley:" class="emoji" alt=":smiley:">
Então tipo, listaDeConta é uma arraylist de Conta1, por Conta2 dar extends em Conta1, eu posso colocar tanto Conta1 quanto Conta2 nessa Arraylist.
Ou seja por exemplo:
ListaDeConta lista = new ListaDeConta();
lista.add(new Conta1(os atributos de Conta1));
lista.saque(Número da conta, valor);
Conta1 não pode ter saldo negativo, porém se eu colocasse lá nos parâmetros o número da conta correspondente a uma Conta1 e um valor que deixasse o saldo negativo, ele entrava no método de saque correspondente ao Conta2(Que aceita ficar com saldo negativo), porém por polimorfismo ele deveria entrar no dele, mas isto não aconteceu. Por isso fiz aquela forçação de “tipoDeConta”, mas valeu pela ajuda, ainda tenho muito que aprender.
Um ArrayList vai aceitar os dois tipos de conta a partir do momento que você declara-lo assim:
List<Conta> contas = new ArrayList<Conta>();
public class Banco {
private List<Conta> contas = new ArrayList<Conta>();
public void abrirConta(String numero, int tipo) {
if (tipo == 0)
contas.add(new Conta1(numero));
else
contas.add(new Conta2(numero));
}
public void retirarDeTodasAsContas(int valor) {
for (Conta conta : contas) {
conta.sacar(valor);
}
}
}
Se a classe Conta for como eu descrevi acima, o método retirarDeTodasAsContas irá disparar uma exceção quando a Conta apontada pela lista for uma Conta2. Isso por causa do polimorfismo do método sacar.
Como eu falei, não seria necessário haver um campo que testasse o tipo de conta. Se você está fazendo isso, é provavelmente um POG.
Meu programa foi totalmente estruturado, nada de OO. Agora vou correr atrás do prejuízo. Valeu pela ajuda/aula Godoy. 