Programação Orientada por Objectos jvo, had Enunciados de exercícios seleccionados de testes e exames POO 1. Considere a linguagem Smalltalk e a classe Point definida com as variáveis de instância x e y. Considere ainda que foi criada a variável global umPonto através da avaliação da expressão umPonto := 0@0. Para cada uma das expressões seguintes indique, justificando sucintamente: i) Quais as mensagens enviadas e quais os seus receptores; ii) Os resultados obtidos na avaliação (com print it). a) umPonto x: -1; y: -2; abs b) umPonto class x: -1 y: -2 abs c) ((umPonto x: -1) y: -2) abs 2. Qual é o resultado da avaliação das seguintes expressões em Smalltalk? Justifique sucintamente: a) 1 + 2 + 3 / 2 b) 0.5 + 1 / 2 class c) #c1 species new 3. Para cada uma das expressões seguintes indique o traçado das mensagens emitidas, e o resultado impresso no Transcript. a) Transcript show: (Array new at: 1 put: ‘olá’) printString b) Transcript show: (Set new add: 200 + Float pi cos) printString 4. Pretende-se desenvolver um programa que guarde informação sobre o seguinte universo: "Uma pessoa pode ser proprietária de vários carros. Um carro tem necessariamente um motor. Um carro tem uma cor e uma marca. O motor é caracterizado por um número, tipo de combustível e cilindrada. Se o motor for a gasolina pretende-se guardar o tipo de carburador. Se o motor for a gasóleo pretende-se guardar o tipo de turbo." Seguindo uma abordagem orientada por objectos, proponha para este universo: a) Um conjunto de classes, e seus relacionamentos, capaz de guardar a informação pretendida. b) Todas as variáveis de instância necessárias (e só as necessárias) nas classes identificadas em a); c) Um objecto (ou instância) de uma das classes identificadas anteriormente. http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 1/4 Programação Orientada por Objectos jvo, had 5. Qual é o resultado da avaliação das seguintes expressões em Smalltalk? Justifique sucintamente: a) 1 + 2 max: 3 * 4 sqrt b) 0 = false == false c) [:x :y | x > y ifTrue: [^1] ifFalse:[^0]] value: 1 value: 2 6. Qual é o resultado da avaliação dos seguintes conjuntos de expressões? Justifique sucintamente. a) | xyz| x := y := z := #(1 #(2 3)). x at: 1 put: ((y at: 2) at: 1). y := x. x at: 1 put: (z at: 1) + 2.0. ^x b) | anArray s | anArray := #(10 20 30 40). s := 0. ((1 to: anArray size) select: [: e | e even]) do: [ :i | s := s + (anArray at: i)]. ^s 7. Dado um inteiro constituído única e garantidamente por zeros e uns, escreva o código que verifique se o número de zeros é igual o número de uns. Escreva código eficiente. 8. Escreva uma expressão que devolva o número de dígitos existentes no factorial de 500. 9. Sabendo que SequenceableCollection, é a super classe abstracta de todas as colecções que admitem índices inteiros, e que o método collect: aBlock está implementado naquela super classe da seguinte forma: collect: aBlock "Avalia aBlock com cada um dos elementos do receptor como argumento. Recolhe os resultados numa nova colecção identica à do receptor. Responde a nova colecção." | newCollection | newCollection := self species withSize: self size. 1 to: self size do: [:index | newCollection at: index put: (aBlock value: (self at: index))]. ^newCollection implemente, naquela super classe, o método deepCollect: aBlock que avalia aBlock com cada um dos elementos do receptor como argumento, mesmo que estes se encontrem http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 2/4 Programação Orientada por Objectos jvo, had dentro de uma ou mais colecções. Recolhe os resultados numa nova colecção idêntica à do receptor. Responde a nova colecção. Exemplo: #(1 2 #(3 4)) deepCollect: [:e | e squared] "responde #(1 4 #(9 16))". 10. Escreva o código que escreveria numa janela de texto Smalltalk que permita abrir um ficheiro de texto para leitura, substituir ocorrências de \b por \begin; de \i por \item e de \e por \end e escrever o resultado em outro ficheiro de código. Use as classes da hierarquia Stream. Se o conteúdo do ficheiro de leitura for: Teste \b \i um \i dois \i três \e Experiência Após a execução do código, o conteúdo do ficheiro de leitura será: Teste \begin \item um \item dois \item três \end Experiência 11. Considere a seguinte expressão: #(1 2 3 4) inject: 0 into: [ :s :a | a even ifTrue: [s+1] ifFalse: [s]] a) Qual o valor respondido pela sua avaliação. b) Reescreva a expressão usando outro iterador sobre o mesmo receptor de modo que produza o mesmo resultado. 12. Implemente o novo iterador do: aBlock exceptFor: anObject que executa a operação especificada no primeiro argumento aBlock para todos os elementos do receptor excepto para os que são iguais as segundo argumento anObject. O método deve ser escrito uma única vez para todas as colecções. 13. Indique o traçado da expressão 1.0 + 2/3 quando se usa dupla distribuição: 14. Indique o traçado da expressão 1 + 2 / 3.0 quando avaliada num sistema que use Dupla Distribuição para efeitos de aritmética mista. http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 3/4 Programação Orientada por Objectos jvo, had 15. Qual é o resultado da avaliação da seguinte expressão Smalltalk? Justifique sucintamente. a) Object class superclass class class b) Object superclass class class class 16. Existe alguma utilidade para METAclasses abstractas? Justifique sucintamente. http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 4/4 Programação Orientada por Objectos jvo, had Solução de exercícios seleccionados de testes e exames POO 1. i) a) umPonto x: -1; y: -2; abs b) umPonto class x: -1 y: -2 abs c) ((umPonto x: -1) y: -2) abs Como na alínea a) ii) a) umPonto x: -1; y: -2; abs (-1@-2) abs 1@2 b) umPonto class x: -1 y: -2 abs Point x: -1 y: 2 -1 @ 2 c) ((umPonto x: -1) y: -2) abs Como na alínea a) 2. a) Como todas as mensagens são binárias a avaliação é efectuada da esquerda para a direita: http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 1/8 Programação Orientada por Objectos jvo, had 1+2+3/2 3+3/2 6/2 3 b) Como mensagens unárias têm prioridade sobre as binárias: 0.5 + 1 / 2 class 0.5 + 1 / SmallInteger 1.5 / SmallInteger <Erro> c) Como todas as mensagens são unárias a avaliação é efectuada da esquerda para a direita: #c1 species new ByteString new ‘’ Nota: Retorna uma nova ByteString vazia. Se em vez da mensagem species fosse enviada a mensagem class, ter-se-ía: #c1 class new ByteSymbol new #‘’ 3. a) Transcript show: (Array new at: 1 put: ‘olá’) printString Array new #( ) at: 1 put: ‘olá’ <error subscript out of bounds> “Pois Array new cria um array com size=0”. Nota: Se a expressão fôr: Transcript show: ((Array new:2) at: 1 put: ‘olá’) printString Array new: 2 #(nil nil) at: 1 put: ‘olá’ #(‘olá’ nil) printString Transcript show: ‘olá’ ‘olá’ b) Transcript show: (Set new add: 200 + Float pi cos) printString Set new Float pi 3.14156 cos http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 2/8 Programação Orientada por Objectos jvo, had 200 + –1.0 Set () add: 199.0 Set (199.0) printString Transcript show: ‘199.0’ 199.0 4. a) Carro, Motor, MotorGasolina, MotorGasóleo, sendo MotorGasóleo e MotorGasolina subclasses de Motor e a classe Carro está associada a (ou tem agregado) uma das subclasses de Motor. b) Classe [Pessoa] Carro Motor MotorGasolina MotroGasóleo Variáveis de instância marca e cor numero, cilindrada tipoCarburador tipoTurbo c) Objecto da classe MotorGasóleo com numero= 45854, cilindrada=1000, tipoCarburador = (...) 5. Sabendo que as mensagens com maior prioridade são as unárias, seguidas das binárias e das com chave, e que a avaliação de expressões é efectuada da esquerda para a direita: a) 1+2 max: 3 * 4 sqrt 1+2 max: 3 * 2 3 max: 3 * 2 3 max: 6 6 b) 0 = false == false false == false true c) [:x :y | x > y ifTrue: [^1] ifFalse: [^0]] value:1 value:2 Passando os valores para as variáveis x e y do bloco e seguindo as precedências de mensagens dentro do bloco: 1 > 2 ifTrue: [^1] ifFalse: [^0] false ifTrue: [^1] ifFalse: [^0] 0 http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 3/8 Programação Orientada por Objectos jvo, had 6. a) Em VW 7.1 não é possível alterar o valor de um literal, como por exemplo a declaração de um array na segunda linha, logo na linha seguinte, na mensagem at:put têm-se um erro. Mas se se assumindo que os arrays são automaticamente tornados mutáveis, como em VW 5, ter-se-ía: |xyz| x := y := z:= #(1 #(2 3)). x at: 1 put: ((y at: 2) at: 1). y:=x. x at: 1 put: (z at: 1) + 2.0. ^x “x, y e z referenciam o mesmo array: #(1 #(2 3))” “y at: 2 referencia o array embutido que na posição 1 tem o valor 2, logo: #(2 #(2 3))” “já referenciam o mesmo array” “como x e y referenciam o mesmo array: “ “retorna: #(4.0 #(2 3))” b) | anArray s | anArray := #(10 20 30 40). s:=0. Seguindo a precedência das mensagens em: ((1 to: anArray size) select: [:e | e even]) do: [ :i | s := s + (anArray at: i)]. ^s têm-se: ((1 to: 4) select: [:e | e even]) do: [ :i | s := s + (anArray at: i)]. #(2 4) do: [ :i | s := s + (anArray at: i)]. s := s + (anArray at: 2) + (anArray at: 4) s:= 0 + 20 + 40 60 7. Como eficiência, entende-se de acordo com as aulas teóricas, utilização criteriosa de recursos. Assim dá-se preferência à reutilização de código. Visto de outra forma, pretende-se enviar o mínimo de mensagens possível. Não é necessário validar se inteiro é constituído apenas por zeros e uns, pois de acordo com o enunciado já é garantido. Assim, assumindo que o inteiro está guardado na variável n, veja-se primeiro uma abordagem pouco eficiente: |nsdu| n:=1011. u := 0. s := n printString. d := s size. s do: [ :i | i = $1 ifTrue: [u := u + 1]]. ^(d-u) = u http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 4/8 Programação Orientada por Objectos jvo, had Seguidamente apresentam-se duas versões mais eficientes, i.e., mais compactas: i) |ns| n:=1010. s := n printString. ^ (s size / (s select: [ :c | c = $1]) size) = 2 ii) |nb| n:=1001. s := n printString. b := Bag withAll: s. ^((b occurrencesOf: $0) = (b occurrencesOf: $1)) 8. 500 factorial printString size “ou 500 factorial log asInteger + 1” 9. deepCollect: aBlock "Evaluate aBlock with each of the values of the receiver as the argument. Collect the resulting values into a collection that is like the receiver. Answer the new collection. Recursive version" | newCollection t | newCollection := self species withSize: self size. 1 to: self size do: [:index | ((self at: index) isKindOf: SequenceableCollection) ifTrue: [ t := (self at: index) deepCollect: aBlock] “recursive call” ifFalse: [ t := aBlock value: (self at: index)]. newCollection at: index put: t]. ^newCollection #( 1 2 # (3 4)) deepCollect: [:e | e squared] --> #(1 4 #(9 16)) 10. | in out c | in := 'c:\original.txt' asFilename readStream. out := 'c:\novo.txt' asFilename writeStream. [in atEnd] whileFalse: [ c := in next. (c = $\) ifTrue: [ c := in next. (c = $b) ifTrue: [ out nextPutAll: '\begin'] ifFalse: [ (c = $i) ifTrue: [ out nextPutAll: '\item'] ifFalse: [(c = $e) ifTrue:[ out nextPutAll: '\end'] ifFalse: [ out nextPut: $\; nextPut: c] ] ] ] ifFalse: [out nextPut: c]. ]. in close. out close. http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 5/8 Programação Orientada por Objectos jvo, had Nota1: Nota2: O ficheiro original.txt deve estar na mesma directoria da imagem. O ficheiro novo.txt será colocado nessa mesma directoria. Se for encontrado uma sequência como por exemplo \z no ficheiro original.txt, como não está prevista qualquer substituição será simplesmente copiada para o ficheiro novo.txt. 11. a) Retorna a contagem de elementos pares, isto é 2. b) c/ var. Temporária |s| s:=0. #(1 2 3 4) do: [:a | a even ifTrue: [s:=s+1]]. ^s s/ var. Temporária (#(1 2 3 4) select: [:a | a even]) size 12. do: aBlock exceptFor: anObject “Efectua uma transformação sobre os elementos do receptor excepto para o objecto anObject. Retorna o receptor, tal como do:” (self reject: [:x | x = anObject ]) do: aBlock Exemplo para workspace: |s| s:=0. #(1 2 3 4) do: [:i | s:=i+1] exceptFor: 2. ^s “-> soma é 8 pois não soma o 2” Nota: Não são excluídos os elementos de anObject se este for uma colecção; Nem isso era pedido. Também não era pedido que funcionasse com blocos como 2º argumento. 13. Pela precedência das mensagens, o traçado decompõe-se em duas conversões: 1.0 + 2/3 = (1.0 + 2) / 3 1.0 + 2 2 sumFromFloat: 1.0 2 asFloat 1.0 + 2.0 “Resultado parcial” 3.0 http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 6/8 Programação Orientada por Objectos jvo, had “Resultado final” 3.0 / 3 3 quotientFromFloat: 3.0 3 asFloat 3.0 / 3.0 1.0 14. 1 + 2 / 3.0 (1 + 2) / 3.0 = 1+2 2 sumFromInteger: 1 “Resultado parcial” 3 “Resultado final” “Soma elementos da mesma classe. Não necessita converter” 3 / 3.0 3.0 quocinetFromInteger: 3 (3 asFloat) / 3.0 1.0 quotientFromInteger: anInteger "em Float" ^anInteger asFloat / self 15. Seguindo a avaliação da esquerda para a direita: a) Object class superclass class class Object class superclass class class Class class class Class class class Metaclasse “a meta classe da classe Object” “a super classe da meta classe de Object” “a meta classe da classe Class” “a classe de todas as meta classes” b) Object superclass class class class nil class class class UndefinedObject class class UndefinedObject class class Metaclasse “Object não tem super classe” “A classe do objecto único nil” “a meta classe da classe UndefinedObject” “a classe de todas as meta classes” Nota: Para a classe Metaclasse se se enviar a mensagem class retorna a sua metaclasse, isto é Metaclasse class, e como todas as metaclasses são instâncias da classe Metaclasse, chega-se a um ponto onde a instanciação é recursiva: Metaclass class Metaclass class class Metaclass class class class Metaclass class class class class (...) http://w3.ualg.pt/~hdaniel/poo -> Metaclasse class -> Metaclasse -> Metaclasse class -> Metaclasse POO 2004/2005 7/8 Programação Orientada por Objectos jvo, had 16. Não. As metaclasses têm por único objectivo descrever a sua instância que é necessariamente uma classe. Toda a metaclasse tem uma só instância; caso contrário não existia, já que a metaclasse é criada automaticamente na altura em que se cria a uma classe. As metaclasses guardam os métodos de classe e os nomes das variáveis de classe (das classes), tal como as classes guardam os métodos de instância e os nomes das variáveis de instância dos objectos. Os objectos guardam apenas os valores das variáveis de instância. http://w3.ualg.pt/~hdaniel/poo POO 2004/2005 8/8