Composição: trocando informações entre objetos

Um dos melhores artifícios do Java é a comunicação entre seus elementos, variáveis, métodos, objetos, classes e coisas que verá mais adiante. Mais que isso, o bacana é que podemos controlar essa comunicação, ela pode ser: pública, privada e protegida.

Nesse tutorial, daremos início a essa comunicação, falando sobre a Composição (Composition), que é simplesmente o ato de passar um objeto para outro, para usar seus métodos ou atributos.

O que é Composição em Java

É instanciar, ou usar, uma classe/objeto em outra(o). É como se elas se comunicassem, trocassem informações. Ou seja, serve para reutilizar dados, sem ter que criar mais código pra isso.
Simplesmente passamos a informação - na forma de Objeto - para outro Objeto, e este se encarrega de obter os dados e como trabalhar em cima dele.

Costuma-se dizer que composição é o ato de delegar trabalho para outro objeto.
Isso deixa seu código mais elegante, menor e mais seguro.


Para que serve a Composição em Java

Como citamos em nosso artigo introdutório sobre Classes e Objetos, a comunicação entre seus dados é essencial.
Talvez não note muito essa necessidade em projetos pequenos e de iniciantes, mas quando for um profissional, vai ter muita dor de cabeça com isso. Através de uma simplificação de projetos reais, vamos mostrar exemplos de códigos e passaremos exercícios para você notar a importância da Composição em aplicações Java.

Demos o exemplo de setores diferentes em uma empresa naquele artigo inicial.
Dificilmente uma empresa de grande porte vai mandar você fazer e ter acesso a todo o sistema, principalmente o setor financeiro.
Geralmente esse é mantido à sete chaves. Mas como expliquei lá, eles podem simplesmente compartilhar certos dados com você, como o salário final de cada funcionário, para você usar em sua classe "Funcionario".
Notou? Você criar sua classe, faz seu projeto e usa dados de outro Objeto/Classe. E o mais importante: é seguro! Você não faz a mínima idéia do que aconteceu lá, de como é calculado as coisas, dos segredos financeiros da empresa etc.

Graças a orientação a objetos - e outras coisas - isso é possível. Assim você não precisa repetir código.
Além da segurança, a Composição em Java faz com que não seja necessário repetir código. Você simplesmente usa o que já foi feito em outra Classe/Objeto, como é o caso do exemplo da empresa.
Imagina se o programador não soubesse Java? Ia ter que repetir todo o código do setor financeiro dentro da classe "Funcionario"?
Acredite, há coisas bizarras sendo feitas por aí.


Herança x Composição

Mais a frente, em nosso curso online de Java, iremos falar sobre uma das mais importantes, e controversas, e usadas funcionalidades do Java: a Herança. Isso nos leva ao encapsulamento de dados.
Não vamos entrar em muitos detalhes agora, mas basicamente herança é capacidade de uma classe herdar dados de outra.
Por exemplo, você cria uma classe mãe. Quer criar uma classe parecida com a mãe - mas com outras funcionalidades, você não precisa reescrever tudo. Basta fazer com que a classe filha herde a classe mãe.

Por exemplo, podemos criar a classe "Carro" quem atributos como "motor", "portas", "carburador" etc, pois todos atributos estão presentes em todos carros. Fazemos então a classe "Fusca" e a classe "Ferrari" herdar a classe "Carro".
Ora, é claro que vamos adicionar mais funcionalidades na classe "Ferrari", pois ela possuir mais atributos que o padrão genérico generalizado da classe "Carro". Mas não deixa de ser um carro.

Essa generalização, o fato de algumas classes herdadas não precisarem de todos os atributos da classe mãe, também devido ao fato de ao se mudar a classe mãe mudar todas as classes filhas e uma porção de outros detalhes, faz com que herança seja um conceito perigoso e não recomendado. Alguns simplesmente abominam a herança.
Não entraremos em detalhe agora, mas usar Composição é inofensivo e bem mais recomendado. Porém, cada caso é um caso.



Exemplo de uso de Composição em Java

Exercício: Descobrindo se um Funcionário chegou atrasado e seu tempo de trabalho. 

Nesse exemplo, vamos criar 2 classes adicionais: "Funcionario" e "Hora"

Vamos criar um funcionário, o 'geddyLee', criar um objeto para armazenar a hora que ele chegou 'horaChegada' e a hora que ele saiu 'horaSaida'.

A partir da hora de chegada, vamos verificar se ele chegou atrasado (após as 8h) e usando informações dos dois objetos da classe "Hora", vamos saber quanto tempo ele trabalhou e armazenar essa informação na variável "tempoTrabalhado", do objeto 'geddyLee' da classe "Funcionario", e vamos guardar a informação caso ele tenha chegado atrasado

Ou seja, vamos trocar bastante informações entre esses objetos !

controleHorario.java

Essa é nossa classe principal, que tem o método main.
Na main, simplesmente criamos os objetos de Hora e Funcionário mencionados no enunciado.
Iniciamos os objetos de "Hora" já com seus valores (hora, minuto,segundo). Você pode mudar a seu gosto, para testes ou pedir ao usuário, através da classe Scanner.

A seguir, a título de informação, ele exibe a hora de chegada, de saída e o tempo total trabalhado em horas.
A main é bem pequena e enxuta, como deve ser.


Hora.java

Essa classe recebe três elementos inteiros: horas, minutos e segundos, e faz um tratamento.
O tratamento é: as horas devem ser inteiros entre 0 e 23, os minutos e segundos devem ser inteiros entre 0 e 59.

Caso não seja, é lançada uma excessão (artíficio para mostrar que ocorreu um erro e a aplicação é encerrada).
Experimente colocar uma data errada para ver a mensagem de erro.

Os métodos dessa classe são simples getters um toString().

Método toString()
O método toString é um método especial, existente em todos os objetos de Java (pois está na classe Objects e todas classes são derivadas desta).

Como o nome pode sugerir, ele serve para retornar uma String.
Vamos formatar uma string com argumentos, por isso vamos usar o método format, para exibir as horas, minutos e segundos no formato: hh:mm:ss

Uma outra característica especial deste método é que ele se torna o padrão e automaticamente invocado, caso tente imprimir um 'objeto'.
Isso mesmo, se colocar apenas um objetos em uma função de print, esse método será invocado.

Por isso , para imprimir na main, fizemos apenas:
System.out.println("Hora de chegada: " + horaChegada);
System.out.println("Hora de saída: " + horaSaida);

Mas poderíamos ter feito:
System.out.println("Hora de chegada: " + horaChegada.toString());
System.out.println("Hora de saída: " + horaSaida.toString());


Funcionario.java

Essa classe que vai recebe a informação de outros objetos. No caso, ela recebe objetos da classe "Hora".
Vamos comentar seus métodos:


  • public double tempoAtraso(Hora horaChegada)
Vamos descobrir o tempo que o funcionário atrasou convertendo a hora de chegada em segundos.
Simplesmente transformamos a hora em que o funcionário chegou em segundos:
horaChegada.getHour()*60*60 + horaChegada.getMinute()*60 + horaChegada.getSecond()
E subtraímos do tempo que ele deveria chegar na empresa (8h00min):
8*3600.0
E dividimos por 3600.0, para o resultado ser um double que representa as horas atrasadas.


  • public double horasTrabalhadas(Hora horaChegada, Hora horaSaida)
Para o cálculo do tempo trabalhado de um funcionário, vamos levar em conta somente as horas trabalhadas.

Primeiro, vamos transformar a hora da saída e a hora da chegada em minutos e subtrair esse valor:
(horaSaida.getHour()*60 + horaSaida.getMinute()) - (horaChegada.getHour()*60 + horaChegada.getMinute())
Agora temos a diferença entre os horários de chegada e saída, em minutos.
Então, dividimos tudo por 60.0 para ter o tempo trabalhado, em horas.

Caso esse tempo seja negativo, é porque você colocou uma data de saída anterior a data de chegada.
Então, um erro, com a explicação, é lançado e aplicação é encerrada.


  • public double getHorasTrabalhadas()
Um simples exemplo de get, que retorna a variável 'tempoTrabalhado'.



Código do nosso programa:

controleHorario.java

public class controleHorario {

    public static void main(String[] args) {

        Hora horaChegada = new Hora(8, 0, 1);
        Hora horaSaida = new Hora(9, 30, 0);
        Funcionario geddyLee = new Funcionario("Geddy Lee", horaChegada, horaSaida);
        
        System.out.println("Hora de chegada: " + horaChegada);
        System.out.println("Hora de saída: " + horaSaida);
        System.out.printf("Horas trabalhadas: %.1f\n",geddyLee.getHorasTrabalhadas());
        

    }

}

Hora.java

public class Hora {
    private int hours,
                minutes,
                seconds;
    
    public Hora (int hours, int minutes, int seconds){
        //preenchendo as horas
        if(hours>=0 && hours <24 )
            this.hours = hours;
        else
            throw new IllegalArgumentException("Hora inválida");
            
        //preenchendo os minutos
        if(minutes >=0 && minutes < 60)
            this.minutes = minutes;
        else
            throw new IllegalArgumentException("Minutos inválidos");
        
        //preenchendo os segundos
        if( seconds >=0 && seconds < 60)
            this.seconds = seconds;
        else
            throw new IllegalArgumentException("Segundos inválidos");
            
                
    }
    
    @Override
    public String toString(){
     return String.format("%d:%d:%d", getHour(), getMinute(), getSecond());
    }
    
    public int getHour(){
        return this.hours;
    }
    
    public int getMinute(){
        return this.minutes;
    }
    
    public int getSecond(){
        return this.seconds;
    }
    
}


Funcionario.java

public class Funcionario {
    private String nome;
    private boolean atraso;
    private double tempoTrabalhado, tempoAtraso;
    
    public Funcionario(String nome, Hora horaChegada, Hora horaSaida){
        this.nome=nome;
        this.tempoAtraso = tempoAtraso(horaChegada);
        
        if(this.tempoAtraso > 0)
            this.atraso=true;
        
        if(atraso){
            System.out.println("Funcionário '" + this.nome + "' atrasado. ");
        }
        
        this.tempoTrabalhado = horasTrabalhadas(horaChegada, horaSaida);
    }
    
    public double tempoAtraso(Hora horaChegada){
        return ((horaChegada.getHour()*60*60 + horaChegada.getMinute()*60 + 
                 horaChegada.getSecond()) - 8*3600.0)/3600.0;
    }
    
    public double horasTrabalhadas(Hora horaChegada, Hora horaSaida){
        double horas = ( (horaSaida.getHour()*60 + horaSaida.getMinute()) - 
                       (horaChegada.getHour()*60 + horaChegada.getMinute()) )/60.0;
        
        if(horas < 0)
            throw new IllegalArgumentException("Hora de saída anterior a hora de chegada");
        
        return horas;
    }
    
    public double getHorasTrabalhadas(){
        return this.tempoTrabalhado;
    }
}


Exercício: Aplicativo Java para um Supermercado

Você foi selecionado para criar um aplicativo - em Java, claro - para um supermercado.
O que o dono do estabelecimento pediu a funcionalidade "Promoção para você", que funciona da seguinte maneira:
Após as 20h, todos os produtos recebem um desconto de 10%.
Aos sábados e domingos esse desconto vale o dia inteiro.

Ou seja, além de ter uma classe para os produtos do supermercado, você deve criar outra com o horário da compra.
Use a técnica de composition para passar o objeto referente ao horário da compra para o objeto referente ao produto que está sendo comprado. Assim, no objeto produto o preço é calculado com base no horário e dia da semana.

Na sua main, peça o preço do produto, dia da semana e horário da compra (hora, minuto e segundos), e devolva o valor final do produto com base naquele horário.

PS: Em uma aplicação real, não seria necessário fornecer esses dados. Eles seriam obtidos por um leitor de código de barras para saber o preço do produto, e pegaria o horário do sistema, pra preencher os dados referentes ao horário.
Pedimos, porém, por questão de aprendizado, já que você não deve ter um leitor desses em casa...

34 comentários:

Anônimo disse...

Uma pergunta como fazer o processo
correto das classes sendo que uma chama a outra sempre dá a
sensação de estar sendo feito errado... no compilador.

O que eu quero dizer é fazendo de
algo que já esta pronto tudo bem parece fácil resolver... Mas e
de algo começado do zero por quem esta iniciando como ficaria
isso? Por onde comecar a criação??


abraços a todos e sucasso ao site.

Apostila Java Progressivo disse...

Como assim um 'processo correto' e 'feito errado' ?
O que acha que tem de errado?

E não está tudo pronto, sempre criamos tudo do 0 aqui no site.

Vá lá no fórum e explique melhor sua dúvida, não deu pra entender.

Anônimo disse...

Muito boa a apostila. Estou adorando... Mas, esta parte achei confusa...

Apostila Java Progressivo disse...

Olá Anônimo,

Pode dizer o que achou confuso, que tentaremos ajudar.

Leonardo Parrillo disse...

Acredito que a postagem do dia 25 quis dizer é:

Quando você está digitando a classe na IDE da ordem que você postou no site, o interpretador te mostra erro.

Pois no começo a classe Hora não existe, a classe Funcionário não existe.

O mesmo acontece quando está criando a classe Funcionário. No construtor você não tem ainda o método "tempoAtraso" e "horasTrabalhadas" nesse caso, durante a digitação o interpretador fala que existe erros.

Pelo que eu entendi ele quer saber qual melhor forma de criar as classes em Java para que isso não ocorra.

Desculpa se estou poluindo seu site.. Estou fazendo cada lição e aprendendo mais a cada dia. É ótimo o site.

Apostila Java Progressivo disse...

Verdade Leonardo, faz sentido o que disse.

Bom, como este código é mais simples, ele foi criado de uma vez, sem muito planejamento. Então a medida que as ideias iam vindo, ia fazendo, criando as classes, via que precisava de um método, aí criava ele, só depois fazer a chamada etc.

Em casos mais profissionais, há uma reunião antes, para planejamento, onde se pensa na diagramação, nas classes e chamadas que serão necessárias.

Em um projeto muito grande, por exemplo, as partes são divididas com diversos programadores, onde um faz uma coisa e o outro faça outra, e no final junta tudo pra testar.

Nesse caso há apenas uma comunicação sem muitos detalhes. Por exemplo, seu chefe pede para você criar uma classe que faça isso e aquilo, recebendo tal informação e tornando outra informação. O outro programador não vai se importar como você fez, vai ficar sabendo só os dados que precisa mandar pra você e como eles retornarão.
Isso se chama acoplamento.

Mas no fim das contas, pra saber como se faz isso em detalhes, só há uma maneira: tentando.

No começo de cada aplicativo nosso, explicamos o que são, para que serve e como funcionam. Uma dia é ler isso e tentar criar seu próprio.

No mais, obrigado pela contribuição Leonardo, pode continuar contribuindo com o site, agradecemos muito, agrega bastante ao conteúdo.

Renato Barata Gomes disse...

Fiz o exercício de controle de funcionário, criando o projeto controleHorario (que possui o main) e 2 classes (Funcionario e Hora). Quando fui compilar, recebi os seguintes erros:

Exception in thread "main" java.lang.NoClassDefFoundError: controlehorario/Funcionario
at controlehorario.ControleHorario.main(ControleHorario.java:19)
Caused by: java.lang.ClassNotFoundException: controlehorario.Funcionario
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

O que pode ter ocorrido?

Parabéns pelo tutorial. Muito bom.

Apostila Java Progressivo disse...

Olá Renato,

O Java é case sensitive, então um nome com uma letra minúscula é diferente de outro de mesmo nome, com a letra em maiúscula.

O nome do nosso arquivo que contém a main é "controleHorario".
E a classe principal dele é "controleHorario"

Se você colocar controlehorario ou ControleHorario, já vai dar erro.

Checa se os nomes da classe que tem a main e o do arquivo .java estão idênticos.

Renato Barata Gomes disse...

Obrigado pela resposta. Realmente havia encontrado um erro em uma declaração de classe.

Agora eu copiei e colei o código da internet para tentar entender o que estava fazendo errado.

Ao rodar o código recebo o seguinte erro:

Erro: Não foi possível localizar nem carregar a classe principal controlehorario.controleHorario
Java Result: 1
CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)

Porque será que isto está ocorrendo?

Apostila Java Progressivo disse...

Renato, geralmente quando isso ocorre é porque a IDE não está achando a classe que tem a main.

Pode ser porque o nome de alguma classe ou do método main está errado ou porque há mais de um projeto na IDE, você clica em rodar e o programa não sabe qual daqueles projetos rodar.

Se tiver com mais de um projeto aberto ali na lateral, clica com o botão direito em cima daquele que você quer rodar e procurar por "Run" ou algo assim.

Se não funcionar, manda um printscreen da sua main pra: programacao.progressiva@gmail.com

José Carlos De Oliveira disse...

Parabéns pelo site e pelo conteúdo! Fazia tempo que não via algo assim... Objetivo e com bom humor!

mas vamos à minha dúvida, que é na formatação da hora. Esta é a saída que estou obtendo:
----------------------------------
run:
Funcionário 'Geddy Lee' atrasado.
Hora de chegada: controlehorario.Hora@1dd7056
Hora de saída: controlehorario.Hora@fa3ac1
Horas trabalhadas: 10,58 h
----------------------------------

Estou usando as seguintes entradas:
Hora horaChegada = new Hora(8, 20, 30);
Hora horaSaida = new Hora(18, 55, 15);

Apaguei o código que havia feito e literalmente copiei o seu, mas o resultado é o mesmo...
Não entendo...

Obrigado.

Apostila Java Progressivo disse...

Opa, José.

Estava faltando implementar a classe toString().

Incluímos ela e demos uma explicação sobre ela, dê uma lida e veja se sanou sua dúvida.

Obrigado por mostrar o erro.

Anônimo disse...

Estou com dificuldade para resolver o exercício referente ao Supermercado. Poderiam postar a solução?
No mais, parabéns pelo trabalho de vocês.
Venho aprendendo muito com o curso.
Obrigado.

Anônimo disse...

Olá,
fiz o exercício e está dando erro quando compilo, informando que os minutos estão inválidos:

Exception in thread "main" java.lang.IllegalArgumentException: Minutos inválidos
at Hora.(Hora.java:14)
at HorasTrabalhadasFuncionarioTeste.main(HorasTrabalhadasFuncionarioTeste.java:5)
Java Result: 1

mas os minutos não estão inválidos:

Hora horaChegada = new Hora(8, 0, 1);

e o código para preencher os minutos também não:

if(minutos >= 0 && minutos < 60){
this.minutos = minutos;
}else{
throw new IllegalArgumentException("Minutos inválidos");
}

poderia me dizer o que está acontecendo?

Desde já, obrigada.

Anônimo disse...

Olá, primeiramente gostaria de dizer que esse site é muito bom mesmo, vcs estão de parabéns.
Gosto principalmente dos exercícios, porém como o amigo acima
eu também estou tendo muita dificuldade nesse exercício do Supermercado.
Já tentei de várias maneiras e sempre
da errado. às vezes até roda e aparece
tudo certo exceto o preço, que mesmo
sendo nos finais de semana ou depois
das 20hs, aparece sem o desconto.

Nino disse...

Olá. Parabéns pelo curso maravilhoso! mas tenho uma dúvida: para que serve aquela expressão antes do método toStrings:

@Override

Anônimo disse...

Fiz o exercicio mas acho que o codigo ficou um pouco grande...

david disse...

Exercicio SuperMercado.

Class: Mercado

package SuperMercado;
import java.util.Scanner;

public class Mercado{
//Metodo feito para simplificar a 'main'
public static void semana(){
System.out.println("Qual o dia da semana?");
System.out.println("1 - Domingo");
System.out.println("2 - Segunda");
System.out.println("3 - Terça");
System.out.println("4 - Quarta");
System.out.println("5 - Quinta");
System.out.println("6 - Sexta");
System.out.println("7 - Sabado");
}

@SuppressWarnings({ "resource" })
public static void main(String[] args){
Scanner input = new Scanner(System.in);

System.out.print("Qual o preço do produto? ");
double preco = input.nextDouble();

System.out.println();
//chamada do metodo semana
semana();
/*
* Proteção para impedir a implementação de um dia fora de questão.
*/
int dia;
do{
dia = input.nextInt();
if(dia<1 || dia>7){
System.out.println("Dia incorreto!");
System.out.printf("Digite Novamente: ");
}
}while(dia<1 || dia>7);


System.out.print("Qual a Hora da compra? (Apenas Horas)");
/*
* Proteção para impedir a implementação de uma hora incorreta.
*/
int h;
do{
h = input.nextInt();
if(h<0 || h>=24){
System.out.println("Hora incorreta!");
System.out.printf("Digite Novamente: ");
}
}while(h<0 || h>=24);

System.out.print("Minutos? (Apenas Minutos)");
/*
* Proteção para impedir a implementação de minutos incorretos.
*/
int m;
do{
m = input.nextInt();
if(m<0 || m>=60){
System.out.println("Hora incorreta!");
System.out.printf("Digite Novamente: ");
}
}while(m<0 || m>=60);

System.out.print("Segundos? (Apenas Segundos)");
/*
* Proteção para impedir a implementação de segundos incorretos.
*/
int s;
do{
s = input.nextInt();
if(s<0 || s>=60){
System.out.println("Hora incorreta!");
System.out.printf("Digite Novamente: ");
}
}while(s<0 || s>=60);

//Criando objeto 'COMPRA' e passando os parametros Hora(h) Minutos(m) e Segundos(s)
HoraCompra COMPRA = new HoraCompra(h, m, s);

/*
* Observe que foi passado o objeto 'COMPRA' como parâmetro isso
* funciona apenas com construtores, não adianta tentar passar em um
* metodo que vai dar erro!
*/
Final PF = new Final(dia, preco, COMPRA);

System.out.println(COMPRA.toString());
System.out.printf("O Preco do Produto é: %.2f", PF.getPF());
}
}


Class: HoraCompra

package SuperMercado;

public class HoraCompra{
private int hours, min, seg;

public HoraCompra(int hours, int min, int seg){
if(hours >= 0 && hours < 24){
this.hours = hours;
}
else{
throw new IllegalArgumentException("Hora Invalida!");
}

if(min >= 0 && min < 60){
this.min=min;
}
else{
throw new IllegalArgumentException("Minutos Invalidos!");
}

if(seg >= 0 && seg < 60){
this.seg=seg;
}
else{
throw new IllegalArgumentException("Segundos Invalidos!");
}
}

public String toString(){
return String.format("%s:%s:%s", gethours(), getMin(), getSeg());
}

public int gethours(){
return this.hours;
}

public int getMin(){
return this.min;
}

public int getSeg(){
return this.seg;
}
}

Class: Final

public class Final {
private double preco;

public Final(int dia, double preco, HoraCompra COMPRA){

if(dia==1 || dia==7){
this.preco=preco * 0.9;
}
else if(COMPRA.gethours() >= 20){
this.preco=preco * 0.9;
}
else{
this.preco=preco;
}
}

public double getPF(){
return this.preco;
}
}

Anônimo disse...

Exercicio:

import java.util.Scanner;

public class CaixaMercado {

static int pedido;
static int hora;
static int minuto;
static int segundo;
static int dia;
static double precofinal;

public static void Menu() {
Scanner Entrada = new Scanner(System.in);

System.out.println("\tProdutos Cadastrados");
System.out.println("1 - Bolacha");
System.out.println("2 - SKOL");
System.out.println("3 - Coca-Cola");

pedido = Entrada.nextInt();

System.out.println("Digite a hora do pedido");
hora = Entrada.nextInt();
System.out.println("Digite os minutos do pedido");
minuto = Entrada.nextInt();
System.out.println("Digite os segundos do pedido");
segundo = Entrada.nextInt();

System.out.println("Digite o dia da Semana");
System.out.println("1 - Segunda");
System.out.println("2 - Terça");
System.out.println("3 - Quarta");
System.out.println("4 - Quinta");
System.out.println("5 - Sexta");
System.out.println("6 - Sábado");
System.out.println("7 - Domingo");

dia = Entrada.nextInt();
}

public static void main(String[] Args) {

Produtos Bolacha = new Produtos(1, "Bolacha", 1.80);
Produtos Cerveja = new Produtos(2, "Skol", 5.00);
Produtos CocaCola = new Produtos(3, "Coca-Cola", 4.00);

Menu();
HorarioCompra Compra = new HorarioCompra(hora, minuto, segundo, dia);
switch(pedido) {
case 1:
precofinal = Produtos.PrecoFinal(Bolacha.getPreco(), Compra);
break;

case 2:
precofinal = Produtos.PrecoFinal(Cerveja.getPreco(), Compra);
break;

case 3:
precofinal = Produtos.PrecoFinal(CocaCola.getPreco(), Compra);
break;
}

System.out.println("Preço da compra = " + precofinal);
}
}

public class Produtos {

private int ID;
private String nome;
private double preco;

public Produtos(int ID, String nome, double preco) {
this.nome = nome;
this.preco = preco;
this.total++;
}

public double getPreco() {
return this.preco;
}

public static double PrecoFinal(double preco, HorarioCompra Compra) {
if(Compra.getDia() >= 6 || Compra.getHora() >=20) {
return preco * 0.9;
}
else
return preco;
}

}

public class HorarioCompra {

private int hora,
minuto,
segundo,
dia;

public HorarioCompra(int hora, int minuto, int segundo, int dia) {
if(hora>=0 && hora<24) {
this.hora = hora;
}
else
throw new IllegalArgumentException("Hora inválida");

if(minuto>=0 && minuto<60) {
this.minuto = minuto;
}
else
throw new IllegalArgumentException("Minuto inválido");

if(segundo>=0 && segundo<60) {
this.segundo = segundo;
}
else
throw new IllegalArgumentException("Segundo inválido");

if(dia>0 && dia<8) {
this.dia = dia;
}
else
throw new IllegalArgumentException("Dia inválido");
}

public int getHora() {
return this.hora;
}

public int getMinuto() {
return this.minuto;
}

public int getSegundo() {
return this.segundo;
}

public int getDia() {
return this.dia;
}

}

Anônimo disse...

Eita que deu um nó agora! >.<

Anônimo disse...

Alguem ai pode me ajudar? estou com duvido o que essa parte do codigo
@Override
public String toString(){
return String.format("%d:%d:%d", getHour(), getMinute(), getSecond());
}

public int getHour(){
return this.hours;
}

public int getMinute(){
return this.minutes;
}

public int getSecond(){
return this.seconds;
}

}

exatamente faz. Se alguem puder me ajudar, ficarei garto.

Anônimo disse...

Pô, mas tu curte Rush mesmo ein.. hasuhas
Parabéns pelo site, muito bem explicado e claro.
Abraço

erkrausz disse...

Eu perdi o sono tentando entender essa "coisa", pensei um dia inteiro mas finalmente entendi... segue meu resultado. Obrigado pelo conhecimento e parebéns pelo conteúdo!
_____________________________________
Produtos.java
public class Produtos{
//variaveis
private String nome, dia;
private double valor,valorDesconto;
private int hora;
private boolean desconto=false;

//method com tratamento e atribuições de variaveis (aqui recebe o objeto Hora)
public Produtos(String nome, double valor,Hora hcompra){
this.nome=nome;
this.valor=valor;
this.hora=hcompra.getHora();
this.dia=hcompra.getDia();
switch(dia){
case "sabado":
desconto=true;
break;
case "domingo":
desconto=true;
break;
default:
if(hora>=20 && hora<25){
desconto=true;
}
}
}
//gets
public String getNome(){
return this.nome;
}
//get com teste para retornar desconto
public double getDesconto(){
if (desconto==true){
return this.valorDesconto=valor-((valor/100)*10);
} else {
return this.valor;
}
}
//get para retornar valores
public double getValor(){
return this.valor;
}

public int getHoras(){
return this.hora;
}

public String getDia(){
return this.dia;
}

}
------------------------------------
Hora.java
public class Hora{
//variaveis
private int horaCompra;
private String dia;
//method recebe variaveis do construtor presente na main e atribui as variaveis
public Hora(int hcompra, String dia){
this.horaCompra=hcompra;
this.dia=dia;
}
//gets necessarios para "jogar" os valores para a classe Produtos.java (veja no

//comentario onde ele "cai")

public int getHora(){
return this.horaCompra;
}

public String getDia(){
return this.dia;
}
}

____________________________________
Caixa.java
import java.util.Scanner;
public class Caixa{
public static void main(String [] args){
//variaveis
String nome, dia;
double valor;
int horaCompra;
Scanner entrada=new Scanner(System.in);
//recebe dados
System.out.println("Nome do produto");
nome=entrada.nextLine();
System.out.print("Dia da semana: ");
dia=entrada.nextLine();
System.out.print("Valor do produto: ");
valor=entrada.nextDouble();
System.out.print("Hora da compra (APENAS HORAS): ");
horaCompra=entrada.nextInt();

//cria objetos (referencia hcompra DENTRO do criador do objeto Produto)
Hora hcompra= new Hora(horaCompra,dia);
Produtos bolacha= new Produtos(nome,valor,hcompra);

//exibe resultados usando a referencia bolacha (objeto Produtos) para

//apontar os "gets"
System.out.println("Valor Integral: R$"+bolacha.getValor());
System.out.println("Valor final: R$"+bolacha.getDesconto());

}
}

Jefferson Rodrigues disse...

Segue minha resolução:(PARTE 1)
PromoçaoPraVoce.java

package promocaopravoce;
import java.util.Scanner;

public class PromocaoPraVoce{

public static void main(String[] args){
double preco;
String diaDaSemana;
int horaCompra;
int minutosCompra;
int segundosCompra;
Scanner entrada = new Scanner(System.in);
Menu menu = new Menu();

System.out.print("Digite o preço do produto: ");
preco = entrada.nextDouble();

System.out.print("Selecione o dia da semana: \n");
menu.exibeDiasDaSemana();
int dia = entrada.nextInt();
diaDaSemana = menu.escolheDiaDaSemana(dia);

System.out.print("Digite a hora da compra: ");
horaCompra = entrada.nextInt();
horaCompra = menu.escolheHora(horaCompra);

System.out.print("Digite os minutos da compra: ");
minutosCompra = entrada.nextInt();
minutosCompra = menu.escolheMinutos(minutosCompra);

System.out.print("Digite os segundos do compra: ");
segundosCompra = entrada.nextInt();
segundosCompra = menu.escolheSegundos(segundosCompra);

Hora hora = new Hora(horaCompra, minutosCompra, segundosCompra);
Produto produto = new Produto(preco, diaDaSemana, hora);

System.out.printf("Preço com Desconto: %.2f\n", produto.getPreco());
System.out.printf("Preço sem Desconto: %.2f\n", preco);
System.out.printf("Desconto de R$ %.2f\n", produto.getDesconto());
System.out.print("Horário da compra: " + hora + " hora(s)");

}
}

Hora.java

package promocaopravoce;

public class Hora {
private int hours;
private int minutes;
private int seconds;

public Hora(int hours, int minutes, int seconds){
//preenchendo as horas
if(hours >= 1 && hours <= 24)
this.hours = hours;
else
throw new IllegalArgumentException("Hora inválida! ");

//preenchendo os minutos
if(minutes >= 1 && minutes <= 60)
this.minutes = minutes;
else
throw new IllegalArgumentException("Minutos Inválidos! ");

//preenchendo os segundos
if(seconds >= 1 && seconds <= 60)
this.seconds = seconds;
else
throw new IllegalArgumentException("Segundos Inválidos! ");
}

public String toString(){
return String.format("%d:%d:%d", getHours(), getMinutes(), getSeconds());
}

public int getHours(){
return this.hours;
}

public int getMinutes(){
return this.minutes;
}

public int getSeconds(){
return this.seconds;
}

}

Jefferson Rodrigues disse...

Minha Solução (PARTE 2)

Produto.java

package promocaopravoce;

public class Produto {
private double preco, desconto;
private String diaDaSemana;
private boolean promocao;


public Produto(double preco, String diaDaSemana, Hora horaDaCompra){
this.promocao = setPromocao(diaDaSemana, horaDaCompra);
this.preco = setPreco(preco);
this.diaDaSemana = setDiaDaSemana(diaDaSemana);
this.desconto = setDesconto(preco);

if(this.promocao)
System.out.println("Produto em Promoção!");

else
System.out.println("Preço Normal!");
}

public String setDiaDaSemana(String diaDaSemana){
String dia = diaDaSemana;

if((diaDaSemana == "segunda") || (diaDaSemana == "terca") || (diaDaSemana == "quarta") ||
(diaDaSemana == "quinta") || (diaDaSemana == "sexta") || (diaDaSemana == "sabado") ||
(diaDaSemana == "domingo")){

dia = diaDaSemana;
}
else
throw new IllegalArgumentException("Dia da semana inválido!");

return dia;
}

public String getDiaDaSemana(){
return this.diaDaSemana;
}

public boolean setPromocao(String diaDaSemana, Hora horario ){
boolean promocao;

if((horario.getHours()*60*60 + horario.getMinutes()*60 + horario.getSeconds()) >= (20*60*60)){
promocao = true;
}else{
if((diaDaSemana == "sabado") || (diaDaSemana == "domingo"))
promocao = true;
else
promocao = false;
}
return promocao;
}

public double setPreco(double preco){
double newPreco;

if(promocao){
newPreco = preco * 0.9;
}else{
newPreco = preco;
}
return newPreco;
}

public Double getPreco(){
return this.preco;
}

public double setDesconto(double preco){
double desconto;

if(promocao){
desconto = preco * 0.1;
}else{
desconto = 0.0;
}

return desconto;
}
public double getDesconto(){
return this.desconto;
}
}

Jefferson Rodrigues disse...

Minha Solução (PARTE 3)

Menu.java

package promocaopravoce;
import java.util.Scanner;

public class Menu {
private String diaDaSemana;

public void exibeDiasDaSemana(){
System.out.println("1 - Segunda");
System.out.println("2 - Terça");
System.out.println("3 - Quarta");
System.out.println("4 - Quinta");
System.out.println("5 - Sexta");
System.out.println("6 - Sabado");
System.out.println("7 - domingo");
System.out.println("Opção: ");
}

public String escolheDiaDaSemana(int dia){
String Dia = "segunda";
do{
switch(dia){
case 1:
Dia = "segunda";
break;
case 2:
Dia = "terca";
break;
case 3:
Dia = "quarta";
break;
case 4:
Dia = "quinta";
break;
case 5:
Dia = "sexta";
break;
case 6:
Dia = "sabado";
break;
case 7:
Dia = "domingo";
break;
default:
System.out.println("Opção Inválida!");
break;
}

}while(dia > 7 || dia < 1 );

return Dia;
}

public int escolheHora(int hora){
Scanner entrada = new Scanner(System.in);

while(hora > 24 || hora < 0){
System.out.println("Hora inválida!");
System.out.print("Digite a hora da compra: ");
hora = entrada.nextInt();

};

return hora;
}

public int escolheMinutos(int minutos){
Scanner entrada = new Scanner(System.in);

while(minutos > 60 || minutos < 0){
System.out.println("Minutos inválidos!");
System.out.print("Digite os minutos da compra: ");
minutos = entrada.nextInt();

};

return minutos;
}

public int escolheSegundos(int segundos){
Scanner entrada = new Scanner(System.in);

while(segundos > 60 || segundos < 0){
System.out.println("Segundos inválidos!");
System.out.print("Digite os segundos da compra: ");
segundos = entrada.nextInt();

};

return segundos;
}
}

Aline disse...

Segue o código do aplicativo do supermercado :)

package br.com.supermercado;

public class Horario {
private String dia;
private int hora;
private int minuto;
private int segundo;

public Horario(String dia, int hora, int minuto, int segundo){
this.dia = dia;
this.hora = hora;
this.minuto = minuto;
this.segundo = segundo;
}

public String getDia(){
return dia;
}

public void setDia(String dia){
this.dia = dia;
}

public int getHora() {
return hora;
}

public void setHora(int hora) {
this.hora = hora;
}

public int getMinuto() {
return minuto;
}

public void setMinuto(int minuto) {
this.minuto = minuto;
}

public int getSegundo() {
return segundo;
}

public void setSegundo(int segundo) {
this.segundo = segundo;
}

}

====================================================================
package br.com.supermercado;

public class Produto {

private float preco;

public Produto(float preco){
this.preco = preco;
}

public float getPreco() {
return preco;
}

public void setPreco(float preco) {
this.preco = preco;
}

public void calculaPreco(Horario hora, Horario dia){
if(hora.getHora()>20 && hora.getHora()<24){
System.out.println("**********GANHOU DESCONTO**********");
preco = preco - (preco * 0.10f);
}

else{
if(dia.getDia().equals("Sabado") || dia.getDia().equals("sabado") || dia.getDia().equals("Domingo") || dia.getDia().equals("domingo")){
System.out.println("**********GANHOU DESCONTO**********");
preco = preco - (preco * 0.10f);
}
}
}
}

========================================================
package br.com.supermercado;

import java.util.Scanner;

public class Controle {

public static void main(String[] args){
@SuppressWarnings("resource")

Scanner entrada = new Scanner(System.in);
int hora, minuto, segundo;
float preco;
String dia;
Horario horario;
Produto produto;

System.out.print("Digite a hora: ");
hora = entrada.nextInt();

System.out.print("Digite o minuto: ");
minuto = entrada.nextInt();

System.out.print("Digite o segundo: ");
segundo = entrada.nextInt();

System.out.print("Digite o dia: ");
dia = entrada.next();

System.out.print("Preco do produto: ");
preco = entrada.nextFloat();

horario = new Horario(dia, hora, minuto, segundo);
produto = new Produto(preco);

produto.calculaPreco(horario, horario);

System.out.println("Preco do produto: "+produto.getPreco());

}
}

Anônimo disse...

Main:

package supermercado01;
import java.util.Scanner;
/**
*
* @author MWK
*/
public class Supermercado01 {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Scanner e = new Scanner(System.in);
int horas, minutos, segundos;
String dia;
float preco;

System.out.println("Digite o dia da compra");
dia = e.nextLine();

System.out.println("Digite a hora da compra");
horas = e.nextInt();

System.out.println("Digite os minutos da compra");
minutos = e.nextInt();

System.out.println("Digite os segundos da compra");
segundos = e.nextInt();

System.out.println("Digite o preço do produto.");
preco = e.nextFloat();

HoraCompra hora1 = new HoraCompra(dia,horas,minutos,segundos);
ProdutoSupermercado mequetrefe = new ProdutoSupermercado(hora1, preco);

System.out.println(hora1);
System.out.printf("O preço do produto é R$ %.2f\n",mequetrefe.getPreco());
}

}

Classe HoraCompra:

package supermercado01;

/**
*
* @author MWK
*/
public class HoraCompra {
private int horas, minutos, segundos;
private String dia;

public HoraCompra(String dia, int horas, int minutos, int segundos){

//recebendo dia
if("segunda".equals(dia)||"terca".equals(dia)||"quarta".equals(dia)||"quinta".equals(dia)||"sexta".equals(dia)||"sabado".equals(dia)||"domingo".equals(dia)){
this.dia=dia;
}
else{
throw new IllegalArgumentException("Dias inválidos.");
}
//recebendo horas
if(horas>=0 && horas<24){
this.horas=horas;
}else{
throw new IllegalArgumentException("Horas inválidas,");
}
//recebendo minutos
if(minutos>=0 && minutos<60){
this.minutos=minutos;
}else{
throw new IllegalArgumentException("Minutos inválidos.");
}
//recebendo segundos
if(segundos>=0 && segundos<60){
this.segundos=segundos;
}else{
throw new IllegalArgumentException("Segundos inválidos.");
}
}
public String getDia(){
return this.dia;
}
public int getHoras(){
return this.horas;
}
public int getMinutos(){
return this.minutos;
}
public int getSegundos(){
return this.segundos;
}
@Override
public String toString() {
return String.format("%s,%02d:%02d:%02d",getDia(), getHoras(), getMinutos(), getSegundos());
}
}

Classe ProdutoSupermercado:
package supermercado01;

/**
*
* @author MWK
*/
public class ProdutoSupermercado {
private float preco;
private String dia;


public ProdutoSupermercado(HoraCompra hora1, float preco){
this.dia = diaCompra(hora1);
this.preco=preco;

if("sabado".equals(this.dia) || "domingo".equals(this.dia)){
this.preco*=0.8;
System.out.println("\nO preço doproduto é "+this.preco);
}else{
if(horaCompra(hora1)>=20){
this.preco*=0.8;
}else
this.preco=this.preco;
}

}
public String diaCompra(HoraCompra hora1){
return hora1.getDia();
}
public int horaCompra(HoraCompra hora1){
return hora1.getHoras();
}
public float getPreco(){
return this.preco;
}
}

Anônimo disse...

Por favor, como faço para inserir o " || " através do NetBean?
Obrigado!

marciel silva disse...

Alguém poderia me auxiliar numa questão ?

crie uma classe UsMoney com duas variáveis de instancia inteiras Dollar e cents. Adicione um construtor com dois parâmetros para a inicialização de um objeto UsMoney .O construtor deve verifica se o valor de cents esta entre 0 e 99.Adicione um método plus() a classe que use um objeto UsMoney como parâmetro .ele dever criar e retornar um novo objeto UsMoney representado a soma do objeto cujo método plus() esta sendo chamado mais o parâmetro , sem modificar os valores dois objeto existentes. Também deve assegurar que o valor da variável de instancia cents do novo objeto esteja 0 e 99.crie também uma classe UsMoneyDemo que teste a classe UsMoney.

ate um certa parte eu entendo , mais na parte que perder adicionar o método plus e usar um objeto UsMoney não entendi.

Gabriella Santos disse...

Olá, pode explicar um pouco mais referente a throw new IllegalArgumentException, pois ainda não compreendi..

Obrigada e parabéns pelo excelente material!

MaxCavalcante disse...

Mercadinho.java - principal

public class Mercadinho {

public static void main(String[] args) {
Scanner entrada = new Scanner(System.in);
int hora, opt, dia;
double preco;
//criei os objetos abaixo sem parametros para que os dados sejam informados pelo usuario.
HoraDia hour = new HoraDia();
HoraDia day = new HoraDia();
Item prod = new Item();

do{//sempre uso um loop pois assim o programa não vai fechar toda vez que terminar uma função ou acontecer algum erro.
System.out.print("\n\nMercadinho Boa Compra."
+ "\n\nEscolha a opção - 1.Comprar - 0.Sair\n: ");
opt = entrada.nextInt();
switch(opt){//uso switch pois é mais fácil para o meu controle.
case 1:
System.out.print("\nQual o dia da semana estamos(1-7): ");
dia = entrada.nextInt();
if (dia>=1 && dia<=7){//aqui mesmo vai verificar se o usuário digitou um dia da semana válido.
if (dia>=2 && dia<=6){
/*observe que se o usuário digitar um dia da semana entre segunda e sexta
o programa pede as horas.
se não for entre segunda e sexta, como o exercício informa, não necessita de horas.
*/

System.out.print("\n\nQual a hora nesse momento: ");
hora = entrada.nextInt();
hour.Hora(hora);//aqui eu jogo o valor da hora no objeto hour e no sue método Hora
}
/*observem que não utilizei um else{ aqui pois, mesmo que seja um dia entre segunda e sexta
o programa tem que passar para a próxima etapa, saber o preço do produto.
e se não for entre segunda e sexta, então o programa já passa para essa etapa,
sem a necessidade de saber as horas, pois não iria influenciar em nada.
*/

System.out.print("\n\nQual o preço do produto: ");
preco = entrada.nextDouble();
day.Dia(dia);
/*aqui eu jogo o valor do dia no objeto day e no seu método Dia
poderia ter jogado diretamente abaixo da entrada do usuário.
mas seria desnecessário se, por acaso, a entrada do usuário for inválida.
*/

prod.Promo(day, hour);
/*Aqui o objeto prod em seu método Promo recebe os valores dos objetos day e hour
*/

System.out.printf("\n\nO valor final do produto é: %.2f.",prod.PrecoFin(preco));
/*E por fim, o objeto prod em seu método PrecoFin irá verificar se tem ou não desconto
então retornará o valor final.
*/

}else
System.out.print("\n\nDia Inválido.");
break;
case 0:
break;
default:
System.out.print("\n\nOpção Inválida.");
}
}while(opt!=0);//digite 0 para sair do programa.
}
}

Continua na próxima postagem...

MaxCavalcante disse...

HoraDia.java

package mercadinho;

public class HoraDia {
private int hora, dia;

public void Dia(int dia){//verifica se o dia está entre 1 e 7 e então joga esse dado no int dia,
if (dia>=1 && dia<=7){
this.dia = dia;
}
else
throw new IllegalArgumentException("Dia Inválido");
}
public void Hora(int hora){//mesma coisa do Dia();
if (hora>=0 && hora<=24){
this.hora = hora;
}
else
throw new IllegalArgumentException("Hora inválida");
}
public int getDia(){
return this.dia;
}
public int getHora(){
return this.hora;
}
}

Item.java

package mercadinho;

public class Item {
private double preco;
private int day, hour, desc=10;
private boolean descont = false;

public void Promo(HoraDia day, HoraDia hour){
/*Primeiro o método irá verificar se é entre segunda ou sexta, se for, irá verificar se está entre as 20 horas e 23 horas
se estiver então o boolean descont será verdadeiro.
se não for entre 20 e 23 horas, então será false.
se não for segunda-sexta, se for sábado ou domingo, então o boolean descont será verdadeiro.

*/

this.day = day.getDia();
this.hour = hour.getHora();

if (this.day>=1 && this.day<=7){
if (this.day>=2 && this.day<=6){
if (this.hour>=20 && this.hour<=23){
descont = true;//boolean se torna verdadeiro caso seja segunda-sexta entre 20 e 23 horas.
}
else{
descont = false;
}
}
else{
descont = true;//boolean se torna verdadeiro caso seja sabado ou domingo.
}
}
else{
descont = false;
throw new IllegalArgumentException("Dia Inválido.");
}
}
public double PrecoFin(double preco){
/*esse método irá verificar se o descont é verdadeiro, caso sim, irá aplicar o valor do desconto,
esse valor do desconto também pode ser informado pelo usuário se o programador desejar.
caso não seja verdadeiro, então ele não aplicará o valor do desconto.
*/

if (descont==true){
this.preco=preco-(preco*desc)/100;//calculo do desconto onde desc tem o valor do desconto em %(10%).
}
else{
this.preco=preco;
}
return this.preco;
}

}

Acho que está muito grande esse código, porém não vejo como diminuir sem deixar grande parte dele na main() e eu não utilizei toString() - até pq não entendi a sua real funcionalidade.

leandroevan disse...

Olá!
Eu não entendi como funcionam os trechos:
throw new IllegalArgumentException("xxxx");
e
@Override

Acho o site muito bom, mas às vezes peca por não dar o mínimo de explicação sobre algum trecho de código utilizado. Para quem é totalmente leigo em programação fica muito difícil exercitar a escrita dos códigos. Acabamos por copiar o código feito, o que prejudica o aprendizado.

Sei que algumas coisas ainda serão ensinadas, porém podia ter pelo menos a ideia do que aquilo faz e como escrever.

Dicas e Novidades de Java por e-mail

Sabe quanto custa um bom livro de java?
Entre R$ 100,00 e R$300,00

Sabe quanto custa um bom curso presencial de Java?
Entre R$ 1.500,00 até R$ 4.000,00

Sabe quanto custa estudar pelo Java Progressivo?
Absolutamente nada.

Porém, também precisamos de sua ajuda e apoio.
Para isso, basta curtir nossa Fan Page e clicar no botão G+ do Google.