Exercicio 4 Capitulo 10 Interfaces apostila Caelum

23 respostas
A

Olá,

Nao entendi o que deve ser feito no exercicio 4 de Interfaces.

interface Conta{ double getSaldo( ); void deposita(double valor); void retira(double valor); void atualiza(double taxaSelic); }

Adapte ContaCorrente e ContaPoupanca para essa modificacao:

class ContaCorrente implements Conta{ }

class ContaCorrente implements Conta{ }

"Algum codigo vai ter de ser copiado e colado? Isso é tao ruim?
Como voce pode diminuir esse copia e cola e centralizar esses codigos repetidos em um lugar só? Pesquisar sobre herança e composicao

Gostaria de um explicaçao, se possivel, em detalhes, pois fiquei curioso em saber como se faz para diminuir esse copia e cola e centralizar esses codigos em um só lugar?
E essa pesquisa sobre heranca e composiçao?

Obrigado.

23 Respostas

willricardo

O que exatamente você não conseguiu fazer ou não entendeu?!!

A

Editei a minha duvida sobre o exercicio 4, pois nao estava sendo claro.
Alguem poderia me explicar?
Obrigado.

lina

Oi,

Vou tentar sem clara e rapida: Interface é uma padronização, ou seja, quando uma classe implementa uma interface,
garante que todas as funcionalidade especificadas pela interface serão oferecidas pela classe.

Tipo, digamos que você cria uma interface com nome EMAIL e nela tem 2 métodos SEND() e RECEIVE() e
Você irá implementar essa interface em sua classe THUNDERBIRD, a sua classe obrigatoriamente terá que
implementar os métodos da interface.

Para maiores detalhes, é melhor que estude um pouco sobre interface no java. ok?!

Tchauzin!

W

Oi!

Nenhum código vai ser copiado e colado, pois a interface não possui implementação, como a lina falou a “Interface é uma padronização, ou seja, quando uma classe implementa uma interface, garante que todas as funcionalidade especificadas pela interface serão oferecidas pela classe.” Só que a implementação deve ser realizada em cada classe., e cada classe pode ter uma implementação diferente dos métodos.

veja esse link: http://www.guj.com.br/article.show.logic?id=123

um abraço!

A

Olá Lina e Willians,

Acho que voces nao entenderam a minha duvida. Isso que postaram sobre interface, eu já sabia.
Vou explicar novamente:

O exercicio começa assim:
4.(opcional) Transforme sua classe Conta em uma interface.

interface Conta{ double getSaldo( ); void deposita(double valor); void retira(double valor); void atualiza(double taxaSelic); }

Adapte ContaCorrente e ContaPoupanca para essa modificacao:

class ContaCorrente implements Conta{ }

class ContaCorrente implements Conta{ }

Em seguida aparece esse questionamentos:
"Algum codigo vai ter de ser copiado e colado?
Isso é tao ruim?
Como voce pode diminuir esse copia e cola e centralizar esses codigos repetidos em um lugar só?
Pesquisar sobre herança e composicao. "
Estas pergunta acima fazem parte do exercicio 4 da Apostila da Caelum.

O que eu quero saber é por qual motivo aparece no exercicio esse questionamento: Como voce pode diminuir esse copia e cola e centralizar esse codigos repetidos em um só lugar?
Este questionamento do exercicio 4 esta sugerindo que existe essa possibilidade de diminuir esse copia e cola e centralizar esse codigos repetidos em um só lugar.
Neste exercicio existe essa possibilidade? Tem uma solução este exercicio?
Se tiver algum instrutor da Caelum para esclarecer esse exercicio seria de grande ajuda.

Obrigado.

Um abraço!

Baratao

Bom…

Posso estar errado mas a primeira coisa que veio a minha mente foi usar classe abstrata.

Voce pode criar um metodo não abstrato que seria igual nas duas classes e os demais voce deixaria abstratos para que sejam implementados nas classes filhas.

Seria isso ou estou errado?

soro

Você não vai copiar código nem nada. Vou vai IMPLEMENTAR os códigos da interface, se você reparou seus métodos na interface não possuem SCORPO e todos seus métodos são abstratos.
Quando você ‘implements’ uma interface, o nome já diz… você vai IMPLEMENTAR a interface.
Agora me diga: Para que eu queria um método sem scorpo? Sem nada a fazer? Vem a questão na qual você diz que já sabe, como a guria falou lá em cima.
Então, se você está usando alguma IDE, a primeira coisa que ela vai falar é que existem métodos a serem implementados. Então… implemente-os. Crio o corpo dos seus métodos. É apenas isso.
Agora se você que deixar o código centralizado para as demais classes, você não deveria usar Interface. Pois você vai ter que implementar os métodos nas duas classes e isso é repetição de código, use Herança. Transforme sua interface em Classe, implemente os métodos nessa classe e então faça com que as duas classes herdem desta superior.

Assim você pode passar Conta para uma classe qualquer que ela vai aceitar ContaCorrent como também ContaPoupança, pois as duas são subclasses de Conta e seu código continuará generico e legal. :slight_smile:

A

Olá,

Pensei em fazer isso tambem, Baratão, usar uma classe abstrata com um metodo nao abstrato que serial igual nas classes filhas! Seria aplicacao de Heranca no exercicio!

Mas, Soro, porque o autor da apostila da Caelum colocou esse questionamento:
Como voce pode diminuir esse copia e cola e centralizar esse codigos repetidos em um só lugar? Pesquisar sobre heranca e composiçao.
Seria possivel aplicar composicao junto com a interface no exercicio?
ou heranca(seguindo a ideia do Baratao) com interface?

Qual(is) seria(m) a(s) solucao(oes) deste exercicio?

Se tiver algum instrutor ou autor da apostila da Caelum para esclarecer e solucionar esse exercicio seria de grande ajuda.

soro

Sim, contanto que você torne sua interface uma classe concreta ou abstrada, assim fazendo com que as demais Contas (Corrente e Poupança) herdem de Conta.

Você vai deixar seu código em Conta e na herança as suas subclasses já herdarão todos os atributos e métodos da classe Pai.

Caso você precise fazer alguma alteração em algum método, não tem problema, você pode alterar o método da classe pai direto na classe filha, basta manter a mesma assinatura, isso claro se a classe filha precisar desta alteração.

Paulo_Silveira

Ola AlunoJava

Sou o autor dessa questão, então vou tentar explanar a minha solução/opinião aqui.

O intuito é mostrar que, apesar de tão falado “evite herança, prefira composição”, a desvantagem de você não fazer herança é não ganhar “de graça” os métodos que são comuns as classes. Isso pode desanimar o iniciante em OO, pois teria de copiar e colar a implementação da classe Conta dos métodos que são comuns e iguais tanto em ContaCorrente quanto ContaPoupanca (getSaldo(), transfere(), por exemplo).

Para evitar esse copiar/colar:

  • criar uma classe abstrata e herda-la, como já era feito anteriormente desse exercício, mas mantendo a interface.
  • criar uma outra classe, por exemplo GerenciadorDeSaldo, onde você fara composição com ela. Essa teria os métodos que trabalham com saldo e são comum as duas, e depois, internamente, você teria algo como:
class ContaCorrente implements Conta {
  private GerenciadorDeSaldo gerenciador = new GerenciadorDeSaldo();
  public double getSaldo() {
    return gerenciador.getSaldoAtual();
  }

  // outros metodos
}

Os métodos que são iguais, você delega diretamente para o gerenciador, os que são diferentes, você ignora por completo o gerenciador, ou talvez use-o e ainda processe algo a mais. Na sala de aula discutimos mais a fundo. Obivamente neste caso, esta solução acaba ficando bastante rebuscada, mas mostra bem a herança X composição.

A

Olá Paulo,

Vou tentar fazer o exercicio com a explicaçao que me passou!

Se nao for pedir demais Paulo, depois, voce poderia colocar a soluçao completa e codificada desse exercicio.

Obrigado pela atenção e pelo esclarecimento!

A

Olá, Paulo

Peço que, se tiver um tempo, poste a soluçao completa e codificada desse exercicio. Quero entender bem esse exercicio e a parte da herança x composiçao.

Obrigado.

lina

Oi,

Então… se você sabe o que é interface você teria resolvido esse problema :wink:

Tchauzin!

A

Oi Lina, :slight_smile:

Nao me leve a mal Linda , mas nao foi minha intençao bancar o sabidao quando voce tentou me ajudar com a minha duvida.
Eu tambem nao estava sendo claro quando postei a duvida para voces.
Voce é uma expert em Java, e eu sou só um Aluno que tem muito a aprender.
A teoria de interface eu realmente tinha estudado, mas na pratica é que o bicho pega. Eu apliquei o tinha me dito lá em cima, mas nao

Um abraço e Tchauzin!

lina

Oi,

Não tem problema! não fiquei chateada, ok?

Levando em consideração o conceito de interface, toda classe que irá implementa-la deverá sobreescrever seus métodos!

Então, sua classe ContaCorrente ficará.:

public class ContaCorrente implements Conta
{
	@Override
	public void atualiza(double taxaSelic) {
		
	}

	@Override
	public void deposita(double valor) {
		
	}

	@Override
	public double getSaldo() {
		return 0;
	}

	@Override
	public void retira(double valor) {
		
	}
}

e sua classe ContaPoupanca ficará.:

public class ContaPoupanca implements Conta
{
	@Override
	public void atualiza(double taxaSelic) {
		
	}

	@Override
	public void deposita(double valor) {
		
	}

	@Override
	public double getSaldo() {
		return 0;
	}

	@Override
	public void retira(double valor) {
		
	}
}

Onde teoricamente, a função dos métodos para cada classe irá ser diferente e você deverá adapta-los de acordo com o especificado. Por exemplo.: (o método getSaldo() presente em ambas as classe) Na classe ContaCorrente simplesmente irá mostrar o saldo. Já na ContaPoupanca existe o aumento do dinheiro depositado (Dependendo da quantidade de dinheiro acrescentado alguns % por mês) então você retornaria esse valor aumentado.

Tchauzin!

A

Oi, Lina

Ok! :smiley:

Fiz isso que voce postou, deu tudo ok.
Mas fui querer aplicar a composiçao com interface, como o Paulo tinha me explicado, e nao conseguir fazer.
Vou estudar mais sobre composicao e tentar fazer de novo.

Obrigado.

Um Abraço.

A

Paulo Silveira:
Ola AlunoJava

Sou o autor dessa questão, então vou tentar explanar a minha solução/opinião aqui.

O intuito é mostrar que, apesar de tão falado “evite herança, prefira composição”, a desvantagem de você não fazer herança é não ganhar “de graça” os métodos que são comuns as classes. Isso pode desanimar o iniciante em OO, pois teria de copiar e colar a implementação da classe Conta dos métodos que são comuns e iguais tanto em ContaCorrente quanto ContaPoupanca (getSaldo(), transfere(), por exemplo).

Para evitar esse copiar/colar:

  • criar uma classe abstrata e herda-la, como já era feito anteriormente desse exercício, mas mantendo a interface.
  • criar uma outra classe, por exemplo GerenciadorDeSaldo, onde você fara composição com ela. Essa teria os métodos que trabalham com saldo e são comum as duas, e depois, internamente, você teria algo como:
class ContaCorrente implements Conta {
  private GerenciadorDeSaldo gerenciador = new GerenciadorDeSaldo();
  public double getSaldo() {
    return gerenciador.getSaldoAtual();
  }

  // outros metodos
}

Os métodos que são iguais, você delega diretamente para o gerenciador, os que são diferentes, você ignora por completo o gerenciador, ou talvez use-o e ainda processe algo a mais. Na sala de aula discutimos mais a fundo. Obivamente neste caso, esta solução acaba ficando bastante rebuscada, mas mostra bem a herança X composição.

Olá Paulo,

Tentei, mas nao consegui chegar a soluçao deste exercicio para evitar esse copiar e colar.
Poderia postar a solução para entendermos a herança x composicao?

Obrigado

B
Herança:
package guj.exemplos.caelumfj11.cap10p7.exerc1;

public interface Conta {

   double getSaldo();
   void deposita(double valor);
   void retira(double valor);
   void atualiza(double taxaSelic);
}
package guj.exemplos.caelumfj11.cap10p7.exerc1.heranca;

import guj.exemplos.caelumfj11.cap10p7.exerc1.Conta;

public abstract class AbstractConta implements Conta {

   private double saldo;

   public double getSaldo() {
      return saldo;
   }

   public void deposita(double valor)  {
      saldo += valor;
   }

   public abstract void retira(double valor);

   public void atualiza(double taxaSelic) {
      // como se calcula isso?
   }
}
package guj.exemplos.caelumfj11.cap10p7.exerc1.heranca;

public class ContaCorrente extends AbstractConta {

   private double limite;
   private CalculadorDeImpostos calc;

   @Override
   public void retira(double valor)  {

      double valorCobrado = valor;

      valorCobrado += calc.impostoDeRenda(valor);
      valorCobrado += calc.impostoSobreOperacoesFinanceiras(valor);
      valorCobrado += calc.outroImpostoArbritario(valor);

      if (valorCobrado > this.getSaldo() + limite)
         throw new SaldoInsuficienteException();

      this.deposita(-valorCobrado);
   }
}
package guj.exemplos.caelumfj11.cap10p7.exerc1.heranca;

public class ContaPoupanca extends AbstractConta {

   @Override
   public void retira(double valor) {
      
      if (valor > getSaldo())
         throw new SaldoInsuficienteException();

      this.deposita(-valor);
   }
}

Composição segue o que o Paulo falou.

É um exemplo um pouco fraco para comparar Composição com Herança, mas posso dizer que se o teu código usa-se o meu framework, usando herança para estender as classes, bastaria eu colocar mais um método abstrato nas minhas classes para que todo o teu sistema em produção parasse, se atualizassem o framework.

O problema da Herança é justamente ser obrigado a seguir as regras que as classes Pai ditam, o que é um acoplamento muito forte. O contrário é verdade também, o autor fica com as mãos amarradas se ele não quiser quebrar o que está implementado nas classes filhas.

É uma economia no código na mesma proporção em que aumenta os riscos.

X

Ola e eu teria como criar um array do Objeto Conta? Com eu faria?

Pois gostaria de acessar a todas outras classe com meu array Conta

tipo

Conta c[]
c= new Conta[10]

c[1].retira()

B
Conta[] c = new Conta[10];

c[0] = new ContaCorrente();
c[1] = new ContaPoupanca();
// mesma coisa para c[2] até c[9]

c[0].deposita(100.0);
c[0].retira(50.0);

double saldoCC = c[0].getSaldo();

c[1].deposita(100.0);
c[1].retira(150.0); // gera um SaldoInsuficienteException, caso você implemente o outro exemplo acima

Note que se o objeto é to tipo Conta, você não pode acessar métodos que só existam nas classes implementadas, mas não existam na interface Conta. Terá que converter os objetos para o tipo deles primeiro para poder fazer isso.

X

Ok digamos que minha classe ContaCorrente tivesse herdado ContaPoupanca atribuido de mais um atributo tipo cheque na classe corrente

public class ContaCorrente extends ContaPoupanca implements Conta{

eu teria que acrescentar um metodo double getCheque() na interface Conta?

Como acessaria este metodo getCheque da classe contacorrente utilizando o array de Conta?

B

Só um aviso primeiro:

Não é considerado muito normal você receber um objeto de um tipo, e querer tratar negócios que existem somente no subtipo dele. Seria a mesma coisa que receber um Object, e ir tratando cada tipo que esse Object pode ser. No final isso vira uma bagunça.

O normal mesmo é você já receber ContaCorrente de primeira.

Mas resolvendo o problema:

Como saber que uma Conta é uma ContaCorrente?

if (c[0] instanceof ContaCorrente) // verifica se o objeto é do tipo ContaCorrente
{
  ContaCorrente cc = (ContaCorrente) c[0]; // esta operação é chamada coerção de tipo (o nome é coerção mesmo)

  Cheque cheque = cc.getCheque();
}
X

ok

obrigado

Criado 30 de julho de 2009
Ultima resposta 19 de set. de 2009
Respostas 23
Participantes 9