Buscar

Herança e Polimorfismo

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 17 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 17 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 17 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

1 
 
FACULDADE DE COMPUTAÇÃO E INFORMÁTICA 
BACHARELADOS EM CIÊNCIA DA COMPUTAÇÃO E SISTEMAS DE INFORMAÇÃO E 
TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS 
Linguagem de Programação I – SEMANA 08 
 
 
TEORIA: HERANÇA 
 
 
 
Nossos objetivos nesta aula são: 
 
 Conhecer o conceito de herança e implementá-lo em Java 
 Conhecer e utilizar apontador super 
 Conhecer e utilizar o operador instanceof 
 Conhecer e implementar polimorfismo por inclusão 
 Conhecer e implementar polimorfismo por coesão ou type 
casting 
 Conhecer as classes empacotadoras ou wrappers. 
 Continuar a praticar com desenvolvimento orientado a testes 
(TDD-Test Driven Development) 
 
 
A referência para esta aula é o Capítulo 10 (Herança) do nosso livro-
texto: 
 
Horstmann, C. Conceitos de Computação com Java. 5.ed. Porto 
Alegre: Bookman, 2009. 
 
Não deixem de ler este capítulo antes e após a aula de hoje! 
 
 
HERANÇA 
 
 Herança é um tipo especial de relacionamento do tipo generalização-especialização, onde 
uma subclasse (mais especializada) herda parte(ou o todo) de uma superclasse (mais 
genérica). 
 
 Um dos objetivos principais da herança é fazer reuso de um código já implementado nas 
superclasses e adicionais os detalhes necessários para que a subclasse que esteja 
estendendo a superclasse seja mais especializada. 
 
 O conceito de herança é uma das palavras-chave que caracterizam o paradigma de 
programação orientada a objetos (POO), juntamente com os mecanismos de abstração de 
tipos abstratos de dados. Assim, o conceito de herança é comum a diversas linguagens de 
programação orientadas a objetos. 
2 
 
 
 Para entendermos a necessidade de herança, vamos relembrar como faríamos com a nossa 
classe BankAccount, caso desejássemos incluir um requisito de tipo de conta: 
 
public class BankAccount { 
 
 private int accountNumber; // número da conta 
 private String password ; // senha da conta 
 private String owner; // proprietário da conta 
 private double balance; // saldo da conta 
 private String type; // tipo da conta 
 
 public BankAccount(int accountNumber, String password, String owner, 
 double balance, String type) { 
 this.accountNumber=accountNumber; 
 this.password=password; 
 this.owner=owner; 
 this.balance=balance; 
 this.type=type; 
 } 
 
 public void deposit(double amount) { 
 // Deposita valor na conta bancária 
 balance += amount; 
 } 
 
 public void withDraw(double amount) { 
 // Retira valor da conta bancária 
 balance -= amount; 
 } 
 
 public double getBalance() { 
 // Consulta o saldo da conta bancária 
 return balance; 
 } 
 
 public int getAccountNumber(){ 
 // Consulta o número da conta bancária 
 return accountNumber; 
 } 
 
 public String getPassword(){ 
 // Consulta a senha 
 return password; 
 } 
 
 public String getOwner(){ 
 // Consulta o proprietário da conta 
 return owner; 
 } 
 
 public String getType(){ 
 // Consulta o tipo da conta 
 return type; 
 } 
} 
3 
 
 Para criarmos uma conta do tipo corrente e outra do tipo poupança, fazemos as seguintes 
instanciações: 
 
BankAccount c = new BankAccount(....,”CONTA CORRENTE”); 
BankAccount p = new BankAccount(...,”POUPANÇA”); 
 
 Queremos, agora, incluir um detalhe específico de cálculo de juros quando a conta for do 
tipo poupança. Uma primeira tentativa para se fazer isto é mostrado abaixo: 
 
public class BankAccount { 
 
 private int accountNumber; // número da conta 
 private String password ; // senha da conta 
 private String owner; // proprietário da conta 
 private double balance; // saldo da conta 
 private String type; // tipo da conta 
 private double interestRate; // taxa de juros na forma de porcentagem 
 
public BankAccount(int accountNumber, String password, String owner, 
 double balance, String type, double interestRate) { 
 ... 
 this.interestRate=interestRate; 
 } 
 
 public void deposit(double amount) {...} 
 
 public void withDraw(double amount) {...} 
 
 public double getBalance() { 
 if (type.equals(“CONTA CORRENTE”)) 
 return balance; 
 else return balance*(1+interestRate/100.0); 
 } 
 
 public int getAccountNumber(){...} 
 
 public String getPassword(){...} 
 
 public String getOwner(){...} 
 
 public String getType(){...} 
 
 public double getInterestRate(){ 
 // Devolve a taxa de juros 
 return interestRate; 
 } 
} 
 
 Embora esta implementação funcione, ela exibe um problema muito sério: perda de coesão. 
Na mesma classe, estão representados os interesses tanto de uma conta corrente, quanto 
de uma poupança. 
4 
 
 Para refatorar a implementação anterior utilizando o mecanismo de herança, vamos 
inicialmente concentrar na classe BankAccount somente os detalhes do correntista e saldo 
e retirar o tipo da conta, conforme mostrado abaixo: 
 
public class BankAccount { 
 
 protected int accountNumber; // número da conta 
 protected String password ; // senha da conta 
 protected String owner; // proprietário da conta 
 protected double balance; // saldo da conta 
 
 public BankAccount(int accountNumber, String password, String owner, 
 double balance){ 
 ... 
 
 } 
 
 public void deposit(double amount) {...} 
 
 public void withDraw(double amount) {...} 
 
 public double getBalance() { 
 return balance; 
 } 
 
 public int getAccountNumber(){...} 
 
 public String getPassword(){...} 
 
 public String getOwner(){...} 
 
} 
 
 Tendo como base a classe BankAccount (superclasse), vamos utilizar o mecanismo de 
herança para construir a classe SavingsAccount (subclasse) para representar uma conta de 
poupança, conforme mostrado abaixo: 
 
public class SavingsAccount extends BankAccount { 
 
 private double interestRate; // taxa de juros 
 
 public SavingsAccount(int accountNumber, String password, String owner, 
 double balance, double interestRate){ 
 super(accountNumber, password,owner,balance); 
 this.interestRate=interestRate; 
 } 
 
 public double savingsBalance(){ 
 // Devolve o saldo da poupança 
 return getBalance()*(1+interestRate); 
 } 
} 
 
 
5 
 
 
 
 
 A classe SavingsAccount estende a classe 
BankAccount através da palavra reservada 
extends. Devido a uma alternativa de projeto da 
Linguagem Java, só podemos estender uma 
classe de cada vez (herança simples). Outras 
linguagens OO como, por exemplo C++, 
permitem herança múltipla, ou seja, estender 
mais de uma classe ao mesmo tempo. 
 
 Em Java, toda classe que não estende 
especificamente uma outra é uma subclasse da 
classe Object. Por exemplo, a classe BankAccount 
estende a classe Object. 
 
 A classe Object tem alguns métodos que fazem 
sentido para todos os objetos, como os métodos 
toString e equals, que você pode utilizar para 
obter uma string que descreve o estado de um 
objeto. 
 
 
 Ao realizar a extensão, tudo o que não for privado em BankAccount poderá ser acessado de 
SavingsAccount. Além disto, SavingsAccount acrescenta dois novos detalhes: 
o um atributo específico para representar a taxa de juros (interestRate) 
o um método específico para calcular o saldo da poupança (savingsBalance) 
 
 As subclasses não têmacesso aos campos privados da superclasse, a não ser que façamos a 
alteração no modificador de acesso. 
 
6 
 
 
MODIFICADOR LIMITE DE VISIBILIDADE 
private Este é o nível de encapsulamento mais restritivo. A visibilidade das 
declarações limita-se à classe onde está definido o atributo/método. 
protected A visibilidade das declarações limita-se à própria classe e às classes 
herdeiras dela. 
“sem especificação de 
modificador” (package) 
A visibilidade das declarações limita-se à própria classe e às classes 
do mesmo package, mas não às classes herdeiras. Classes herdeiras 
não precisam ser do mesmo package. 
public Estas declarações são sempre acessíveis. 
 
 No construtor da classe SavingsAccount, estamos reutilizando o construtor da classe 
BankAccount, acessado com o apontador super. Podemos utilizar de três maneiras: 
o super(....) invoca o construtor da superclasse 
o super.id acessa o atributo da superclasse identificado por id 
o super.m(...) acessa o método da superclasse identificado por m 
 
 Quando não houver confusão entre o nome de identificadores da superclasse e da 
subclasse, o operador super pode ser suprimido. O mesmo ocorre no caso de acesso a 
métodos. Na classe do método savingsBalance(), estamos acessando o método getBalance() 
sem usar super, uma vez que não há confusão de nomes entre SavingsAccount e 
BankAccount. 
 
 Para se instanciar uma conta corrente e uma poupança com a refatoração da herança, 
fazemos: 
BankAccount c = new BankAccount(...); 
SavingsAccount p = new SavingsAccount(...); 
 
 
7 
 
POLIMORFISMO 
 O polimorfismo é a habilidade de uma ou mais classes responder a uma mesma 
mensagem de forma diferente. 
 A Taxomia de Cardelli e Wegner que classifica o polimorfismo em categorias e 
subcategorias: 
 
 Vimos o polimorfismo Ad-Hoc de sobrecarga: permite que um nome de método seja 
usado mais do que uma vez com diferentes quantidades ou tipos de parâmetros. A 
seleção do método adequado é feita com base em comparação dos tipos ou quantidade 
dos parâmetros 
 Mesmo nome de método, parâmetros diferentes 
 
 Vimos também o polimorfismo universal de inclusão: A sobrescrita (override) é a 
implementação de métodos em subclasses que possuem o mesmo nome e assinatura 
de métodos de sua superclasse, com o objetivo de anular o comportamento que o 
método apresentava na superclasse ou acrescentar novas instruções. 
 Mesmo nome de método, mesmos parâmetros 
 
 Vimos o polimorfismo paramétrico, Genéricos em Java, em que um único método é 
codificado, e ele trabalhará uniformemente num intervalo de tipos. Um exemplo: 
 ArrayList <String> list = new ArrayList<String>(); 
 
 Dizemos que a classe ArrayList é uma classe genérica e os colchetes angulares em torno 
do tipo String informam que String é o parâmetro de tipo. 
 Você pode substituir String por qualquer outra classe e obter um tipo diferente de lista. 
 
 Veremos o polimorfismo de coerção e o polimorfismo de inclusão. Porém, antes vamos 
formalizar uma classe empacotadora. 
 
 
8 
 
Classes Empacotadoras 
 
 Números não são objetos em Java, então você não pode inserir diretamente na lista de 
Array. Ou seja, não pode formar ArrayList <double>. 
Porém, antes você deve transformá-lo em objeto por meio das classes empacotadoras 
(wrappers). 
 
 
 
 
Cada objeto de classe empacotadora contém um valor do tipo primitivo correspondente. Por 
exemplo, um objeto da classe Double contém um valor do tipo double. 
 
A conversão entre tipos primitivos e classes empacotadoras correspondentes é automática. 
Esse processo é chamado de auto-empacotamento ou auto- boxing. 
 
Por exemplo, se atribuir um número a um objeto Double, o número é automaticamente 
“colocado em uma caixa [box]”, a saber, um objeto empacotador. 
 
Double d = 29.95; // auto-empacotamento; ↔ Double d = new Double(29.95); 
 
Inversamente objetos de classes empacotadoras são automaticamente “desempacotados” para 
tipos primitivos. 
double x = d; // auto-desempacotamento ↔ double x = d.doubleValue(); 
 
Portanto, listas de arrays de números são simples e diretas. Basta lembrar-se de utilizar o tipo 
empacotador quando você declarar a lista de arrays e então usar o auto-empacotamento. 
 
ArrayList <Double> data = new ArrayList <Double> (); 
data.add (29.95); 
double x = data.get(0); 
9 
 
POLIMORFISMO AD-HOC POR COERÇÃO (TYPE CASTING) 
 
 É o meio de contornar a rigidez de tipos monomórficos. A linguagem dá suporte à 
coerção através de um mapeamento interno entre tipos. O tipo que está sendo 
mapeado é chamado coargido. 
 Usamos a coerção para converter um tipo em que outro tipo diferente. 
 Exemplo: 
 
double balance = “a lot”; //Erro: tipos incompatíveis 
int dollars = 2; 
double balance = dollars; //Ok: legal armazenar um inteiro em um double 
double balance; 
int dollars = balance; //Erro: não podemos atribuir um ponto flutuante a um 
inteiro 
 
 Temos que converter o valor de ponto-flutuante para inteiro usando uma coerção. 
int dollars = (int) balance; //Casting 
 
 Temos que usar coerção em Java, pois a conversão perde informação. Temos que 
confirmar que concordamos com essa perda de informação. Uma coerção sempre tem a 
forma: (nomeDoTipo) expressão 
 
EXERCÍCIO TUTORIADO 
1. Vamos supor que você deseje um valor truncado em dólares, deixando de lado a parte 
fracionária. Como proceder? 
 
 
2. Usar simplesmente uma coerção para converter um ponto-flutuante para inteiro não é 
sempre uma boa ideia. Vamos supor que você deseje um valor aproximado em dólares 
ao invés de deixar de lado a parte fracionária, como o trecho de código a seguir. 
double price = 44.95; int dollars = (int) price; 
Como você pode melhorar para promover o arredondamento? 
 
 
 
 
 
10 
 
 A operação de cast de objetos é semelhante à operação de cast de tipos primitivos, 
sendo que aqui deseja-se uma conversão dentro de uma hierarquia. 
 
 O type casting aplicado em objetos tem as seguintes características: 
o É possível fazer cast de classes desde que estejam em uma mesma hierarquia; 
o Não podemos fazer cast entre classes "irmãs", tal como entre Funcionario e 
Cliente; 
o O cast não representa uma mudança estrutural do objeto; 
 Existem dois tipos de type casting, são eles: 
o Cast up: conversão para classes localizadas nos níveis acima da hierarquia; 
o Cast down: conversão para classes localizadas nos níveis inferiores da hierarquia. 
 
 Cast Up: 
o Com base na hierarquia de classes, podemos concluir que: 
o Todo Cliente é uma Pessoa e toda Pessoa é um Object; 
o Portanto, podemos realizar a operação de cast up, visualizando um objeto da 
classe Cliente como Pessoa ou Object, mas o objeto não perderá definitivamente 
suas características de Cliente 
o O cast up pode ser explícito ou automático 
 As atribuições permitidas entre variáveis de superclasse e de subclasses são: 
o Superclasse  Superclasse 
o Subclasse  Subclasse 
o Superclasse  Subclasse 
 
 
EXERCÍCIO TUTORIADO 
O que ocorre em cada linha do trecho de código 
Cliente c = new Cliente(); ___________________________________________________ 
Pessoa p = (Pessoa) c; _____________________________________________________ 
Pessoa p2 = c; _____________________________________________________ 
Pessoa p3 = new Cliente();___________________________________________________ 
Object o = (Object) c; _____________________________________________________ 
Object o = c; _____________________________________________________11 
 
 Cast Down: 
o A operação de cast down é oposta à operação de cast up, isto é, ao invés de 
generalizarmos um objeto vamos especializá-lo; 
o Se um objeto é criado como Cliente, e sofre um cast up para Pessoa, é possível 
fazer o cast down para voltar a visualizá-lo como Cliente. 
 Exemplo: 
o Lembrando que: Todo Cliente é uma Pessoa, mas nem toda Pessoa é um Cliente; 
o Se um objeto é criado e declarado como Pessoa, não é possível fazer o cast 
down para transformá-lo em Cliente; 
o Quando for possível realizar a operação de cast down, deverá ser feita sempre 
de forma explícita. 
EXERCÍCIO TUTORIADO 
Diga se é válida ou não cada atribuição. Justifique sua resposta. 
Cliente c = new Cliente(); ________________________________________________ 
Pessoa p = c; ________________________________________________ 
Cliente c2 = (Cliente)p; _______________________________________________ 
Pessoa p2 = new Pessoa(); ________________________________________________ 
Cliente c3 = (Cliente)p2; _______________________________________________ 
 
 
 Na conversão de tipos primitivos, perdemos informação e dizemos ao compilador que 
concordamos. 
 Na conversão de tipos de instância, corremos o risco de causar uma exceção e dizemos 
ao compilador que concordamos em correr esse risco. 
 Para ter a segurança de que a coerção terá sucesso, é melhor testá-la antes de colocá-la 
em prática. 
 O operador instanceof testa se um determinado objeto é instância de uma 
determinada classe. Ele retornará true se o objeto for uma instância da classe (ou de 
suas subclasses) e false, caso contrário. 
 
 Retomando a nossa classe BankAccount e SavingsAccount, outra possibilidade de 
instanciação de poupança é da seguinte forma: 
BankAccount p = new SavingsAccounts(...); //Casting up 
 
Porém, se invocarmos o método savingsBalance() diretamente de p, receberemos um erro 
de compilação, pois savingsAccount() não está definido em BankAccount. 
Para contornar isto, podemos verificar dinamicamente qual o tipo está armazenado em p e 
realizar um casting para invocar o método corretamente: 
12 
 
if (p instanceof SavingsAccount) 
 System.out.println(((SavingsAccount) p).savingsBalance()); 
 
POLIMORFISMO POR INCLUSÃO 
 
 Na implementação da nossa classe SavingsAccount, utilizamos um método para consultar o 
saldo com nome savingsBalance, conforme mostrado abaixo: 
public class SavingsAccount 
 extends BankAccount { 
 
 private double interestRate; // taxa de juros 
 
 public BankAccount(int accountNumber, String password, String owner, 
 double balance, double interestRate){ 
 
 super(accountNumber, password,owner,balance); 
 this.interestRate=interestRate; 
 } 
 
 public double savingsBalance(){ 
 // Devolve o saldo da poupança 
 return getBalance()*(1+interestRate); 
 } 
} 
 
 Porém, se quisermos manter o mesmo nome getBalance() utilizado na superclasse 
BankAccount, podemos utilizar o recurso de polimorfismo por inclusão: definimos métodos 
com a mesma assinatura tanto na superclasse quanto na subclasse. Abaixo, temos a 
refatoração da nossa implementação acima para explorar o polimorfismo por inclusão: 
public class SavingsAccount 
 extends BankAccount { 
 
 private double interestRate; // taxa de juros 
 
 public BankAccount(int accountNumber, String password, String owner, 
 double balance, double interestRate){ 
 
 super(accountNumber, password,owner,balance); 
 this.interestRate=interestRate; 
 } 
 
 public double getBalance(){ 
 // Devolve o saldo da poupança 
 return super.getBalance()*(1+interestRate); 
 } 
} 
 Neste exemplo, observe que foi fundamental o uso do apontador super para diferenciar 
entre o getBalance() da classe SavingsAccount e aquele da classe BankAccount. 
13 
 
EXERCÍCIOS TUTORIADO 
 
Tendo como base a classe BankAccount, implemente uma nova classe LawAccount via herança 
para representar contas vinculadas a processos jurídicos. Numa conta deste tipo, precisamos 
armazenar o motivo da conta vinculada como um texto (por exemplo, “Custos advogatícios da 
União”), a data da criação da conta e data em que a conta poderá ser liberada. Além disto, 
contas vinculadas possuem uma taxa de administração que deve ser descontada do saldo no 
momento do seu resgate. Faça uso do mecanismo de polimorfismo por inclusão. 
Sugestão: para datas, utilize a classe Date do pacote java.util. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15 
 
ATIVIDADE DE LABORATÓRIO 
 
Na semana passada, implementamos uma coleção de objetos do tipo BankAccount através da 
classe Bank, fazendo a leitura a partir de um arquivo. Nesta atividade, vamos expandir esta 
implementação permitindo que a classe Bank armazene tanto as contas normais 
(BankAccount) quanto poupanças (SavingsAccount). Para isto, utilizando a metodologia TDD: 
1. Refatore a classe Bank para que consiga representar, na mesma coleção, tanto objetos do 
tipo BankAccount quanto SavingsAccount. 
 
2. Refatore o construtor de Bank para monte a estrutura da coleção de contas utilizado, agora, 
o seguinte formato de arquivo: 
Número de contas 
Número da Conta 1#Senha da Conta 1#Proprietário da Conta 1#saldo da Conta1 
Número da Conta 2#Senha da Conta 2#Proprietário da Conta 2#saldo da Conta2#taxa juros 
... 
Número da Conta N#Senha da Conta N#Proprietário da Conta N#saldo da ContaN 
 
Se a linha de uma conta contiver quatro parâmetros, ela deve ser instanciada como um 
objeto do tipo BankAccount. Caso a linha tenha cinco parâmetros, ela deve ser instanciada 
como um objeto do tipo SavingsAccount. 
3. Refatore o método sort(...) para que ordene esta nova coleção em ordem crescente de 
saldo. O saldo de uma conta de poupança deve se considerado com o saldo normal + juros. 
 
4. Implemente um método ArrayList<BankAccount> accounts() que devolva somente os 
objetos do tipo BankAccount armazenados na coleção de Bank. 
 
5. Implemente um método ArrayList<SavingsAccount> SavingsAccounts() que devolva 
somente os objetos do tipo SavingsAccount armazenados na coleção de Bank. 
 
Junto com o projeto, entregue a classe principal com os testes de sua implementação. 
 
 
16 
 
EXERCÍCIOS EXTRA-CLASSE 
 
1. Implemente, na classe Bank, um método changeAccount(...) para substituir os dados de 
uma conta atual (oldAccount), caso exista, pelos dados de uma nova conta (newAccount): 
 
public void changeAccount(BankAccount oldAccount, BankAccount newAccount){...} 
 
 Seu método deve receber tanto contas normais quanto poupanças. 
 
2. Refatore, na classe Bank, o método de busca linear do método find(...) para o método de 
busca binária. Seu método deve receber tanto contas normais quanto poupanças. Sugestão: 
utilize o método sort() implementado no laboratório. 
 
3. Implemente, na classe Bank, um método importAccounts(...), que recebe uma instância da 
classe Bank e importa todas as contas desta instância. Casa haja conflito de números de 
conta, as duas contas com números iguais deverão ser mantidas. 
 
public void importAccounts(Bank b){...} 
 
 Seu método deve permitir a importação tanto de contas normais quanto poupanças. 
 
4. Implemente, na classe Bank, uma versão polimórfica do método sort() para, ao invés de 
ordenar a própria coleção de contas, devolver uma cópia ordenada deste coleção, 
mantendo a coleção inicialna sua forma original: 
 
public void sort(ArrayList<BankAccount> ord){…} 
 
 Seu método deve permitir a ordenação tanto de contas normais quanto poupanças. 
 
5. Seja n um inteiro e x um número de ponto flutuante. Explique a diferença entre: 
n = (int) x; e 
n = (int) Math.round(x); 
 
 
6. Seja n um inteiro e x um número de ponto flutuante. Explique a diferença entre: 
n = (int) (x + 0.5); 
e 
n = (int) Math.round(x); 
Para quais valores de x eles dão o mesmo resultado? Para quais valores de x eles dão resultados 
diferentes? 
 
 
17 
 
7. Quais são os valores das expressões a seguir? Em cada linha, suponha que: 
double x = 2.5; 
double y = -1.5; 
int m = 18; 
int n = 4; 
String s = "Hello"; String t = "World"; 
 
a. x + n * y - (x + n) * y 
b. m / n + m % n 
c. 5 * x - n / 5 
d. Math.sqrt(Math.sqrt(n)) 
e. (int) Math.round(x) 
f. (int) Math.round(x) + (int) Math.round(y) 
g. s + t 
h. s + n 
i. 1 - (1 - (1 - (1 - (1 - n)))) 
j. s.substring(1, 3) 
k. s.length() + t.length() 
 
 
8. Quais destas condições retornam true? Verifique na documentação Java os padrões de 
herança. 
a. Rectangle r = new Rectangle(5, 10, 20, 30); 
b. if (r instanceof Rectangle) . . . 
c. if (r instanceof Point) . . . 
d. if (r instanceof Rectangle2D.Double) . . . 
e. if (r instanceof RectangularShape) . . . 
f. if (r instanceof Object) . . . 
g. if (r instanceof Shape) . . . 
 
9. O que há de errado com o laço a seguir? 
double[] data = new double[10]; 
for (int i = 1; i <= 10; i++) 
 data[i] = i * i; 
 
Explique duas maneiras de corrigir o erro. 
 
10. Implemente os métodos toString, equals e clone para todas as subclasses da classe 
BankAccount. Escreva testes de unidade que verificam se os seus métodos funcionam 
corretamente. Certifique-se de testar que uma conta bancária contém objetos provenientes 
de uma combinação de classes de BankAccount.

Outros materiais