Instituto Superior de Engenharia de Lisboa Licenciatura em Engenharia de Electrónica e Telecomunicações e de Computadores 4ª Lista de exercícios de PROGRAMAÇÃO Semestre de Inverno 2012-2013 - 9-11-11 Parte I (exercícios resolvidos) 1. A contagem de tempo pode ser organizada e foi em termos duma classe onde se definem as variáveis de instância e os métodos de instância que os objectos podem usar. Com se pode ver pelo diagrama UML foram definidos: - 4 construtores; - 3get´s obter os valores das variáveis; - 4set´s modificar os valores das variáveis; - 5 métodos de operação: public void subtrairTempo( Tempo t ); public void somarTempo( Tempo t ); public Tempo copiarTempo( Tempo t ); public Tempo toString( Tempo t ); public void escreverTempo(String msg ); - Conceitos de: overloading ->métodos com o mesmo nome e diferentes nos parâmetros overriding ->métodos com a mesma assinatura assinatura dum método -> é o nome e os seus parâmetros. Estude o código destes programas que é composto por duas classes java, a saber: Tempo.java e AplicacaoTempo.java, na primeira classe define o Tempo a na outra define-se uma aplicação onde se instanciam objectos e se chamam os métodos para realizar as operações inerentes à contagem e gestão de tempo. public class AplicacaoTempo{ public static void main( String[] args ) { //instanciar e/ou criar 3 objectos do tipo Tempo: t1,t2,t3 Tempo t1=new Tempo(); Tempo t2=new Tempo(); Tempo t3=new Tempo(); //t4 é uma referencia para um objecto que ainda NAO existe. Está iniciado a null Tempo t4=null; //iniciar objectos Tempo. As variáveis de instancia: t1,t2, t3 ficam com os valores t1.setTempo(20,11,25); t2.setTempo("09:12:31"); t3.copiarTempo(t1); //operar com os objectos do tipo Tempo t1.escreverTempo("Tempo t1 "); t2.escreverTempo("Tempo t2 "); t3.escreverTempo("Copiar o Tempo t1 para t3 "); t1.subtrairTempo(t2); t1.escreverTempo("Tempo t1=t1-t2 => "); t1.somarTempo(t3); t1.escreverTempo("Tempo t1=t1+t3 => "); t4=t2; //afectação de referencias, i.é. se alterar o t4 altera também o t2 t4.setHora(10);//actualiza a hora de t4, mas tambén de t2 t4.escreverTempo("Tempo Alterado t4 "); t2.escreverTempo("Tempo Tambem Alterado t2 "); } } Classe Tempo.java public class Tempo { //Variaveis de instancia //privadas, ou seja , acessíveis somente dentro da classe e fora da classe através de //métodos a definir com esse propósito, denominados de getter´s //três variáveis de instancia - a informação associada ao objecto “aquilo que o caracteriza” private int hora; private int min; private int seg; //Métodos de instancia especiais: Os construtores //Construtor -- métodos especial tem por objectivo INICIAR variavel(is) de instancia(s) //construtor sem parâmetros explicito i.é. definido por programação public Tempo() { //está a ser iniciado por omissão, dado que o seu código está em comentário //setTempo(0, 0, 0); //hora=min=seg=0; } //Construtor com dois parâmetros public Tempo( int h, int m ) { setHoraMinuto(h, m); } //Construtor com três parâmetros public Tempo( int h, int m, int s ) { setTempo(h, m, s); } //Construtor de cópia public Tempo( Tempo t ) { setTempo(t.hora, t.min, t.seg); } // metodo de cópia de t para tt public Tempo copiarTempo( Tempo t ){ Tempo tt=new Tempo(); tt.setTempo(t.hora, t.min, t.seg); return tt; } //Métodos de ACESSO às variáveis de instância //três métodos de ACESSO para CONSULTA -- saber/obter o valor da variável de instancia hora public int getHora(){ return hora;} public int getMin() { return min; } public int getSeg() { return seg; } //seis método de ACESSO para MODIFICAR -- altera o valor de variáveis de instancia public void setHoraMinuto( int h, int m ) { hora = h; min = m; } public void setTempo( int h, int m, int s) { hora = h; min = m; seg = s; } public void setHora( int h) { hora = h; } public void setMinuto( int m) { min = m; } public void setSegundo( int s){ seg = s; } public void setTempo( String t ){ //o formato de string data será: hh:mm:ss elaborar codigo para este efeito String aSt, mSt, dSt; aSt=t.substring(0,2); mSt=t.substring(3,5); dSt=t.substring(6); hora=Integer.parseInt(aSt); //converter string´s de Integer para int min =Integer.parseInt(mSt); seg =Integer.parseInt(dSt); } //Métodos de Operação "propriamente ditos" (Methods the 0peration action) //Retorna o objecto Tempo com a soma horária entre o this e o Tempo t passado em parâmetro //public Tempo somarTempo( Tempo t ) { //Actualiza o objecto this com a soma horária entre o this e o Tempo t passado em parâmetro public void somarTempo( Tempo t ) { int somaSeg = this.seg + t.seg; int somaMin = this.min + t.min; int somaHora = this.hora + t.hora; if( somaSeg >= 60 ) { somaSeg -= 60; ++somaMin; } if( somaMin >= 60 ) { somaMin -= 60; ++somaHora; } if( somaHora >= 24 ) { somaHora -= 24;} //criar o objecto res do tipo Tempo iniciado com os calculos //da soma entre this e t afectados nas variaveis somaHora e somaMin this.seg = somaSeg; this.min = somaMin; this.hora = somaHora; //Tempo res = new Tempo(somaHora, somaMin, somaSeg); //return res; } //Métodos de Operação "propriamente ditos" (Methods the 0peration action) //Retorna o objecto Tempo com a diferença horária entre this e o Tempo t em parâmetro //public Tempo subtrairTempo ( Tempo t ) { //Actualiza o objecto this com a diferença horária entre this e o Tempo t em parâmetro public void subtrairTempo( Tempo t ) { int difSeg = this.seg - t.seg; int difMin = this.min - t.min; int difHora = this.hora - t.hora; if( difSeg < 0 ) { difSeg += 60; --difMin; } if( difMin<0 ) { difMin += 60; --difHora; } // Se this < t, faz-se o seguinte: if( difHora < 0 ) { difHora += 24; } this.seg = difSeg; this.min = difMin; this.hora = difHora; //Tempo res = new Tempo(difHora, difMin, difSeg); //return res; } //método toString() é redefinido (override) de Object para "dar formato de string" // às variáveis de instancia public String toString() { String str = ""; if( hora < 10 ) str += "0"; str += hora + ":"; if( min < 10 ) str += "0"; str += min + ":"; if( min < 10 ) str += "0"; str += seg; return str; } public void escreverTempo(String msg ){ System.out.println(msg+this); } } 2. A classe calendário também é uma classe útil para a gestão do tempo ano, meses e dias e, por isso, estude o seguinte código: AplicacaoData.java Instancia os objectos e chama os métodos. Data.java Define as variáveis de instância e os métodos de instância bem como um método de classe. public class AplicacaoData{ public static void main( String[] args ) { Data hoje = new Data(Data.dataPcDoCalendarioGregoriano()); hoje.escreverData("Data Hoje "); //instanciar e/ou criar 3 objectos do tipo Data Data d1=new Data(); Data d2=new Data(); Data d3=new Data(); //o d4 é uma referencia para um objecto que ainda NAO existe. Está null Data d4=null; // //iniciar objectos d1 e d2,para as suas variáveis de instancia recebem os valores d1.setData(2013,5,10); d2.setData("2013/05/15"); // //Tendo os objectos instanciados com valores vamos agora efectuar operações sobre Data d1.escreverData("Data d1 "); d2.escreverData("Data d2 "); d2.dataAmanha(); d2.escreverData("Data d2 "); d1.dataNdiasDepois(6); d1.escreverData("Data d1 "); } } Data.java //Calendário Gregoriano (Papa Gregório XIII), ano de 1582 até aos nossos dias... //http://pt.wikipedia.org/wiki/Calendário_gregoriano //http://www.mat.uc.pt/~helios/Mestre/H01orige.htm public class Data { //variaveis de instancia do objecto private int ano; private int mes; private int dia; public Data(){}; public Data(int a, int m, int d){ano=a; mes=m; dia=d; }; public Data(Data d){ano=d.ano; mes=d.mes; dia=d.dia;}; //------------------ METODOS ACESSO às variáveis de instancia------------------// ---- METODOS de ACESSO para MODIFICAR as variáveis de instancia ------//Todos os métodos que actualizam variáveis de instancia começam por set........() public void setAno( int a){ ano=a; } public void setMes( int m){ mes=m; } public void setDia( int d){ dia=d; } public void setData( int a, int m, int d){ dia=d; mes=m; ano=a; } public void setMesDia( int a, int m ){ mes=m; ano=a; } public void setData( String data ){ //o formato de string data será: aaaa-mm-dd elaborar codigo para este efeito String aSt, mSt, dSt; aSt=data.substring(0,4); mSt=data.substring(5,7); dSt=data.substring(8); ano=Integer.parseInt(aSt);//unboxing necessario de Integer para converter string mes=Integer.parseInt(mSt); dia=Integer.parseInt(dSt); } // ---- METODOS de ACESSO para CONSULTAR as variaveis de instancia --------public int getAno(){ return ano; } public int getMes(){ return mes; } public int getDia(){ return dia; } // ---- METODOS de OPERAÇÃO --------private boolean bissexto(){ int a=ano; return a % 4==0 && (a % 100 != 0 || a % 400==0); } public int diasDoMes() { int res=31; //o mes já está valido entre 1 e 12 entao o switch é mais compacto switch( mes ){ case 2: res= bissexto() ? 29: 28; break; case 4: case 6: case 9: case 11: res=30; } return res; } public void dataAmanha(){ ++dia; // o dia de amanhã é mais um dia, exceptos os casos particulares if( dia>diasDoMes() ){ //inicio do proximo mes dia=1; if( ++mes > 12 ){ //inicio do proximo ano mes=1; ++ano; } } } public void dataNdiasDepois(int n){ for( int i=1; i<=n; ++i ) dataAmanha(); } public void escreverData(String msg){ System.out.println(msg+" "+ano+"/"+(mes<10?"0":"")+mes+"/"+(dia<10?"0":"")+dia); } //----------------- Bloco dos METODOS static -------------------------------------//este metodo usa a biblioteca java.util.GregorianCalendar public static Data dataPcDoCalendarioGregoriano(){ java.util.GregorianCalendar t=new java.util.GregorianCalendar(); java.util.Date dataCompleta = t.getTime(); //dá a data e tempo completo //o acesso aos itens da data do calenadrio gregoriano da biblioteca java realiza-se //atraves de numeros que se seguem; int h=t.get(11); //acesso a hora int m=t.get(12); //acesso a minuto int s=t.get(13); //acesso a segundo int ano=t.get(1);//acesso a ano int mes=t.get(2);//o mes é varia de 0 a 11, logo temos que somar mais um ao mes int dia=t.get(5);//acesso a dia int diaDaSem=t.get(7);//o dia da semana é : 1(dom),2(2ªf), ...7(sáb). String[] nomeDias={"","Dom","2.feira","3.feira","4.feira","5.feira", "6.feira","Sab"}; System.out.print("DATA e TEMPO em formato SEPARADO lido do PC Tempo: "+ h+":"+m+":"+s+" Data: "+dia+"-"+(mes+1)+"-"+ano); System.out.println(" Dia da Semana: "+nomeDias[diaDaSem]+"\n\n"); return new Data(ano,mes,dia); } //----------------- Bloco dos METODOS static -------------------------------------} Parte II (exercícios por resolver e que saíram em teste de PG) Programação Semestre de Verão 2009-2010 - 1ª Época 30-06-2010 Grupo III As classes acima descritas em UML modelam um leilão de peças. Na classe Leilao a variável de instância pecas contém numeroPecas disponíveis para leiloar, cada uma delas com um valor mínimo de oferta. A variável de instância ofertas contém numeroOfertas ofertas pendentes. Cada oferta identifica a peça sobre a qual incide o valor de oferta, assim como o nome de quem efectuou a oferta. De acordo com o diagrama acima especificado, implemente os seguintes métodos: 1) a) [2] Realize o método Oferta melhorOferta(Peca peca) da classe Leilao que retorna a oferta com o valor mais elevado e que corresponda à peça indicada. Havendo várias ofertas de igual valor retorna a primeira que encontrar. Se não encontrar ofertas para a respectiva peça então retorna null. b) [2] Realize o método boolean novaOferta(Peca peca, double valor, String nome) da classe Leilao que permite efectuar uma nova oferta para uma peça já existente, satisfazendo os seguintes critérios: (1) O valor a oferecer tem de ser superior ao valor mínimo da peça. (2) Se já existir uma oferta para a mesma peça e existir coincidência no nome da pessoa que ofereceu, então bastará actualizar o valor na respectiva oferta. O método retorna true se conseguir criar ou actualizar uma oferta, false caso contrário. c) [2] Realize o método Peca[] semOfertas() da classe Leilao. O método retorna um array com todas as peças para as quais não existe nenhuma oferta. Programação Semestre de Inverno 2009-2010 - 1ª Época 18-01-2010 Grupo III (6 Valores) No desenvolvimento de um sistema informático de suporte à gestão de álbuns foi desenvolvido o diagrama UML seguinte: A classe Discoteca tem duas variáveis de instância privadas: numeroAlbuns, e albuns. A primeira é um inteiro com o número de álbuns existentes na discoteca e a segunda é um array com referências para os vários objectos que representam álbuns. O array tem referências diferentes de null entre os índices 0 e numeroAlbuns-1. Os álbuns são referidos por ordem alfabética do seu título (ou seja, o índice 0 refere o álbum com o menor título e o índice numeroAlbuns-1 o álbum com o maior). A classe Album tem três variáveis de instância privadas: titulo, artista e musicas. A primeira é o título do álbum, a segunda é o nome do artista e a terceira é um array com referências para os vários objectos que representam músicas. O array está totalmente preenchido com referências para objectos Musica. [2] Realize o método double obterDuracaoTotal() da classe Album que calcula e retorna o número total de minutos das várias músicas que compõem o álbum. 1) [2] Realize o método Album[] obterAlbunsComDuracaoMinima(int duracao) da classe Discoteca que retorna um novo array onde cada elemento refere um álbum da discoteca cuja duração é igual ou superior ao parâmetro duracao. [2] Realize o método boolean adicionarAlbumOrdemAlfabetica(Album alb) da classe Discoteca que realiza a inserção ordenada do álbum passado por parâmetro. O método retorna false se não houver espaço para mais albuns, e true caso contrário. 2)