Prévia do material em texto
Classes abstratas
Apresentação
Em orientação a objetos, o conceito de classes abstratas está relacionado à estrutura de herança.
Geralmente, as classes abstratas são classes genéricas na estrutura de herança e não podem ser
instanciadas por não se referirem a classes concretas. Portanto, uma classe abstrata serve única e
exclusivamente para ser estendida.
A principal característica das classes abstratas está na impossibilidade de elas serem instanciadas,
permitindo somente a herança das características provenientes de outros objetos. As classes
abstratas são de extrema importância na programação orientada a objetos (POO), principalmente
em cenários em que existe a necessidade de criar objetos a partir das subclasses de uma classe
geral, e não a partir dela mesma.
Nesta Unidade de Aprendizagem, você vai conhecer mais sobre classes abstratas e sua aplicação, o
conceito de herança e os passos que devem ser seguidos para construir uma aplicação utilizando
essas classes.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Identificar o que é classe abstrata e o que é método abstrato.•
Definir herança.•
Construir uma aplicação usando classes abstratas.•
Infográfico
Uma classe abstrata é implementada em Java para representar entidades e conceitos abstratos,
sendo considerada a classe pai. Ao declarar uma classe, utiliza-se a palavra-chave abstract, o que
permite que sirvam como superclasses. Além disso, uma classe abstrata define um modelo
(template) para determinar uma funcionalidade, mas é a partir das classes derivadas que os
comportamentos específicos são construídos.
Um método abstrato é todo aquele que não tem implementação, ao passo que uma classe abstrata
não pode ser instanciada e define somente parte de uma implementação. O processo de herança é
definido quando uma classe existente adiciona novos métodos e campos para as classes filhas.
Para compreender como as classes abstratas podem ser construídas em Java, confira este
Infográfico.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/c6510ae2-16f7-4d79-ba5a-b0e052aaa448/27189da3-c6a9-4240-abcd-5e206593cdf6.png
Conteúdo do livro
Uma característica importante da POO é o conceito de classe abstrata. Usando classes abstratas,
você pode declarar classes que definem somente parte de uma implementação, deixando para as
classes estendidas o fornecimento de implementações específicas de alguns ou todos os métodos.
No capítulo Classes abstratas, base teórica desta Unidade de Aprendizagem, você vai compreender
o conceito e a aplicação das classes abstratas em Java, analisando a construção de códigos que
ajudem a entender a sua importância na POO. Serão diferenciados os conceitos de método
abstrato e classe abstrata, além da sua relação com a herança de objetos.
Boa leitura.
Ken Arnold, ex-engenheiro sênior do Sun Microsystems Laboratories, é um grande especialista em
projeto e implementação orientada a objetos. Ele foi um dos arquitetos originais da tecnologia
Jini™ e engenheiro chefe da tecnologia JavaSpaces™ da Sun.
James Gosling é um Sun Fellow e CTO do Grupo de Desenvolvimento da Plataforma da Sun
Microsystems. Projetou a linguagem de programação Java original, implementou seu compilador
e a máquina virtual originais, e, mais recentemente, contribuiu para a Real-Time Specification de
Java. Um dos mais respeitados programadores da indústria, ele recebeu o prêmio de Excelência em
Programação da Software Development do ano de 1996.
David Holmes é diretor da DLTech Pty Ltd, localizada em Brisbane, Austrália. Especialista em
sincronização e concorrência, participou do grupo de especialistas JSR-166 que desenvolveu os novos
utilitários de concorrência. Ele também contribuiu para a atualização da Real-Time Specification de
Java e passou os últimos anos trabalhando em uma implementação desta especificação.
A756l Arnold, Ken
A linguagem de programação Java [recurso eletrônico] / Ken Arnold,
Jamoes Gosling, David Holmes ; tradução Maria Lúcia Blank Lisbôa. – 4. ed. –
Dados eletrônicos. – Porto Alegre : Bookman, 2007.
Editado também como livro impresso em 2007.
ISBN 978-85-60031-61-0
1. Computação – Linguagem de programação. I. Gosling, James.
II. Holmes, David. III. Título.
CDU 004.438JAVA
Catalogação na publicação: Juliana Lagôas Coelho – CRB 10/1798
Catalogação na publicação: Júlia Angst Coelho – CRB 10/1712
3.7 Classes e Métodos Abstratos
Uma característica externamente útil da programação orientada a objetos é o conceito de
classe abstrata. Usando classes abstratas você pode declarar classes que definem somen-
te parte de uma implementação, deixando para as classes estendidas fornecer implemen-
tações específicas de alguns ou todos os métodos. O oposto de abstrato é concreto – uma
classe que possui somente métodos concretos, incluindo implementações de quaisquer
métodos abstratos herdados de superclasses, é uma classe concreta.
Classes abstratas auxiliam quando algum comportamento é definido para a maioria ou todos
os objetos de um dado tipo, mas outros comportamentos fazem sentido somente para classes
particulares e não para uma superclasse geral.Uma classe como essa é declarada abstract,
e cada método não implementado na classe também é marcado como abstract. (Se você
necessita definir alguns métodos mas você não precisa providenciar qualquer implementação,
você provavelmente vai querer usar interfaces, que são descritas no Capítulo 4.)
Por exemplo, suponha que você quer criar uma bateria de testes de medidas de desem-
penho para fornecer uma infra-estrutura para escrever código para benchmarks. A im-
plementação da classe deve entender como dirigir e medir o desempenho, mas ela pode
não saber antecipadamente qual benchmark será executado. A maioria das classes abs-
tratas se enquadra num padrão no qual uma área de conhecimento particular da classe
exige que outra pessoa providencie uma parte que está faltando – isto é comumente co-
nhecido como padrão “Método Gabarito”. Em muitos casos os métodos especialistas
são bons candidatos a serem final, de modo que o conhecimento não possa ser com-
prometido de algum modo. Neste exemplo de medidas de desempenho, a parte que está
faltando é o código que precisa ser avaliado. Aqui está como uma classe como esta po-
deria se parecer:
abstract class Benchmark {
abstract void benchmark();
public final long repeat(int count) {
long start = System.nanoTime();
for (int i = 0; i < count; i++)
benchmark();
return (System.nanoTime() – start);
}
}
Qualquer classe com métodos abstratos precisa ser declarada abstract. Esta redundân-
cia auxilia o leitor a ver rapidamente que esta classe é abstract, sem ter que inspecio-
nar a classe para ver se algum método é declarado abstract.
O método repeat fornece a especialidade em benchmark. Ele pode medir o tempo de
uma execução de count repetições de benchmark. O método System.nanoTime retor-
na um timestamp em nanosegundos – ver páginas 594-595. Pela subtração do horário ini-
cial do horário final, você obtém uma aproximação do tempo despendido executando o
benchmark. Se a medição de tempo necessita se tornar mais complexa (talvez medir o
tempo de cada execução e calcular estatísticas sobre as variações), este método pode ser
melhorado sem afetar nenhuma implementação em qualquer classe estendida de seu có-
digo especializado de benchmark.
CAPÍTULO 3 • ESTENDENDO CLASSES 111
O método abstract benchmark deve ser implementado em cada subclasse que não se-
ja também abstract. Isto se deve ao fato de não haver implementação nesta classe, ape-
nas uma declaração. Aqui está um exemplo de uma extensão de Benchmark simples:
class MethodBenchmark extends Benchmark {
/** Nada faz, apenas retorna. */
void benchmark() {
}
public static void main(String[] args) {
int count = Integer.parseInt(args[0]);
long time = new MethodBenchmark().repeat(count);
System.out.println(count+ " métodos em " +
time + " nanosegundos");
}
}
Esta classe mede o tempo necessário para invocar um método vazio benchmark, mais a
sobrecarga do laço. Você agora pode medir invocações de métodos executando a aplica-
ção MethodBenchmark com o número de vezes a ser repetido o teste. O valor de count
é obtido a partir dos argumentos do programa e decodificado usando o método par-
seInt da classe Integer sobre o argumento string, como descrito em “Conversões de
Strings” na página 294.
Qualquer classe pode sobrescrever métodos de sua superclasse para declará-los abs-
tract, convertendo um método concreto em um abstrato naquele ponto da árvore de ti-
pos. Esta técnica é útil, por exemplo, quando a implementação default da classe é inváli-
da para uma parte da hierarquia de classes.
Você não pode criar um objeto de uma classe abstract porque poderia não existir uma
implementação válida para alguns métodos que bem poderiam ser invocados.
Exercício 3.5: Escreva uma nova classe estendida que faça mais medidas, tal como
quanto tempo demora a execução de um laço de zero até algum parâmetro passado.
Exercício 3.6: Altere Veiculo para que ela tenha uma referência a um objeto FonteE-
nergia que é associada com Veiculo em seu construtor. FonteEnergia deve ser uma
classe abstract, porque a medida de capacidade de um objeto TanqueGasolina dife-
re da medida de um objeto Bateria. Coloque um método abstract vazio em Fon-
teEnergia e implemente-o nas classes TanqueGasolina e Bateria. Adicione um
método start a Veiculo que assegure que a fonte de energia não está vazia.
3.8 A Classe Object
A classe Object é a raiz da hierarquia de classes. Cada classe, direta ou indiretamente,
estende Object e portanto uma variável do tipo Object pode se referir a qualquer obje-
to, seja uma instância de classe ou um array. Por exemplo, a classe Attr pode guardar um
atributo de qualquer tipo, e assim seu campo value foi declarado como sendo do tipo
Object. Uma classe como essa não pode armazenar tipos primitivos diretamente, mas
pode conter referências de classes invólucro associadas – ver Capítulo 8.
112 A LINGUAGEM DE PROGRAMAÇÃO JAVA
A classe Object define vários métodos que são herdados por todos os objetos. Estes mé-
todos pertencem a duas categorias: métodos utilitários gerais e métodos que suportam
threads. Suporte a threads é abordado no Capítulo 14. Esta seção descreve os métodos
utilitários e como eles afetam classes. Os métodos utilitários são:
public boolean equals(Object obj)
Compara o objeto receptor com o objeto referido por obj para verificar a igualda-
de, retornando true se eles possuem o mesmo valor e falso se eles não possuem.
Se você quer determinar se duas referências se referem ao mesmo objeto, você po-
de compará-las usando == e !=. O método equals se preocupa com igualdade de
valor. A implementação default de equals em Object assume que um objeto é
igual somente a si mesmo, testando se this == obj.
public int hashCode()
Retorna um código hash para este objeto. Cada objeto possui um código hash para
uso em tabelas hash. A implementação default retorna um valor que é geralmente
diferente para diferentes objetos. Ele é usado para armazenar objetos em coleções
hash, como descrito no Capítulo 21.
protected Object clone() throws CloneNotSupportedException
Retorna um clone deste objeto. Um clone é um novo objeto que é uma cópia do ob-
jeto sobre o qual clone é invocado. Clonagem é discutida na próxima seção.
public final Class<?> getClass()
Retorna um token de tipo que representa a classe deste objeto. Para cada classe T
existe um token de tipo Class<T> (lido como “classe de T”) que é uma instância
da classe genérica Class, descrita em “A Classe Class” nas páginas 365-366.
Quando invocado sobre uma instância de Object, este método vai retornar uma
instância de Class<Object>; quando invocado sobre uma instância de Attr irá
retornar uma instância de Class<Attr>, e assim por diante.
protected void finalize() throws Throwable
Finaliza o objeto durante a coleta de lixo. Este método é discutido com detalhes em
“Finalização”, nas páginas 407-408.
public String toString()
Retorna uma representação string do objeto. O método toString é implicitamen-
te invocado sempre que uma referência de objeto é usada dentro de uma expressão
de concatenação de string como um operando do operador +. A versão Object de
toString constrói um string contendo o nome da classe do objeto, um caractere
@ e uma representação hexadecimal do código hash da instância.
Ambos os métodos, hashCode e equals podem ser sobrescritos se você quiser fornecer
uma noção de igualdade diferente da implementação default fornecida pela classe Ob-
ject. O default é que quaisquer dois objetos diferentes não são iguais e seus códigos
hash são usualmente distintos.
Se sua classe possui a noção de igualdade na qual dois objetos diferentes podem ser
iguais, esses dois objetos devem retornar o mesmo valor de hashCode. O mecanismo
usado por coleções hash se apóia em equals retornando true quando encontra uma
chave de mesmo valor na tabela. Por exemplo, a classe Strings sobrescreve equals pa-
CAPÍTULO 3 • ESTENDENDO CLASSES 113
ra retornar true se dois objetos String possuem o mesmo conteúdo. Ela também so-
brescreve hashCode para retornar um hash baseado no conteúdo do String, de modo
que dois strings com o mesmo conteúdo possuam o mesmo hashCode.
O termo identidade é usado para igualdade de referência: se duas referências são idênticas,
então == entre as duas será true. O termo equivalência descreve igualdade de valor – obje-
tos que podem ou não ser idênticos, mas para os quais equals vai retornar true. Assim se
pode dizer que a implementação default de equals é que equivalência é o mesmo que iden-
tidade. Uma classe que define uma noção mais ampla de igualdade pode fazer que objetos
que não são idênticos sejam equivalentes, sobrescrevendo equals para retornar true com
base no estado dos objetos, em vez de suas identidades. Algumas tabelas hash, tais como ja-
va.util.IdentityHashMap, são preocupadas com a identidade de objetos, e não a equi-
valência. Se você precisa escrever uma tabela hash como essa, você quer códigos hash cor-
respondentes à identidade de objetos, e não a seus estados. O método System.identity-
HashCode retorna o mesmo valor que a implementação de hashCode da classe Object po-
deria retornar para um objeto se não for sobrescrito. Se você simplesmente usa hashCode
sobre os objetos que você está armazenando, você poderia ter um código hash baseado em
equivalência, não em identidade, o que poderia ser muito menos eficiente.
Exercício 3.7: Sobrescreva equals e hashCode para ColorAttr.
3.9 Clonar Objetos
O método Object.clone ajuda você a escrever métodos clone para sua próprias classes.
Um método clone retorna um novo objeto cujo estado inicial é uma cópia do estado atual
do objeto sobre o qual clone foi invocado. Alterações subseqüentes no novo objeto clo-
nado não devem afetar o estado do objeto original.
3.9.1 Estratégias para Clonagem
Existem três importantes fatores na escrita de um método clone:
• A interface Cloneable vazia, a qual você deve implementar para providenciar
um método clone que pode ser usado para clonar um objeto3.
• O método clone implementado pela classe Object, que faz um clone simples
através da cópia de todos os campos do objeto original para o novo objeto. Este
método funciona para muitas classes, mas pode haver necessidade de ser suple-
mentado por um método que o sobrescreva.
• A CloneNotSupportedException, que pode ser usada para sinalizar que um
método clone de uma classe não deveria ter sido invocado.
Uma dada classe pode ter uma, dentre as quatro atitudes seguintes, perante clonagem:
• Suportar clone. Tal classe implementa Cloneable e declara seu método clone
para não lançar exceções.
114 A LINGUAGEM DE PROGRAMAÇÃO JAVA
3
Cloneable deveria ter sido escrita como Clonable, mas o engano foi constatado tarde demais para ser corrigido.
Dica do professor
Uma classe abstrata é formada pormétodos abstratos, sendo caracterizada por seus atributos e
pelos métodos implementados que, em conjunto, integram as subclasses. Ao implementar uma
classe abstrata, construtores são definidos para permitir que sejam implementadas as iniciações
necessárias e a utilização dos métodos, o que garante que uma subclasse (direta ou indireta)
execute o construtor da classe abstrata e herde suas características.
Nesta Dica do Professor, você vai acompanhar a implementação de classes e métodos abstratos em
uma estrutura de herança e compreender como acontecem a concatenação das classes e a
instanciação das subclasses.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/5e367189383a4d6afb380af01e2324ba
Exercícios
1) Para representar objetos projetados do mundo real para a programação, diferentes
elementos são necessários. Ao implementar um código em Java, as classes são utilizadas
para declarar atributos e métodos. Um tipo de classe muito comum na linguagem é a classe
abstrata.
Marque a alternativa que melhor define as classes abstratas.
A) Classes abstratas auxiliam quando algum comportamento é definido para a maioria ou para
todos os objetos de dado tipo.
B) Classes abstratas são aquelas que não têm métodos.
C) Classes abstratas apenas definem como os objetos serão criados.
D) Classes abstratas definem seus atributos como privados.
E) Classes abstratas são conhecidas como interfaces.
2) Em classes abstratas, temos um padrão de acordo com o qual uma área de conhecimento
particular de uma classe exige que outra pessoa providencie uma parte que está faltando.
Além de ser conhecido como Template-Method, também podemos nos referir ao recurso
como:
A) modificador de acesso.
B) sobrescrita.
C) passagem de parâmetros.
D) subclasses.
E) método gabarito.
De forma genérica, um método em Java pode definir uma função, sub-rotina ou
procedimento. Em algumas linguagens, mas não em Java, existe o conceito de métodos
globais. Em Java, todos os métodos precisam ser definidos dentro de uma classe, como os
métodos abstratos.
3)
Sobre os métodos abstratos, é correto afirmar que:
A) não podem ser usados em outras classes.
B) são métodos sem implementação.
C) são aqueles escritos com a palavra private.
D) não podem ser implementados por outras classes.
E) não podem receber valores por parâmetros.
4) Alguns conceitos podem parecer semelhantes em Java como classes abstratas e interfaces
ou quando classes abstratas e métodos abstratos são comparados. O método abstrato
define a assinatura e não contém código diferente daquele que ocorre nas interfaces. A
classe abstrata define atributos e métodos implementados, definindo o acesso às subclasses.
Em relação aos conceitos de classe e métodos abstratos, assinale a alternativa correta.
A) Quando têm métodos abstratos, as classes devem ser declaradas abstratas.
B) Não se pode criar objetos de uma classe abstrata.
C) Cada método não implementado na classe abstrata é marcado com abstract.
D) O oposto de abstrato é concreto.
E) Classes abstratas fornecem a implementação de um ou mais métodos.
5) Com base na programação de objetos em Java, podemos vincular muitos conceitos do
mundo real com o mundo da programação. O mesmo ocorre com o conceito de herança, em
que as classes refletem o comportamento de outras. Nesse processo, temos os conceitos de
superclasse e subclasse.
Em relação à herança em orientação a objetos, assinale a alternativa correta.
A) O conceito de herança refere-se a classes que herdam membros da mesma classe.
B) Uma classe genérica é aquela que tem membros únicos.
C) Quando uma subclasse herda um método abstrato da superclasse, este deve ser
implementado.
D) Quando uma subclasse herda um método abstrato da superclasse, este não deve ser
implementado.
E) Um dos indicativos para criar herança é quando temos atributos diferentes entre duas ou
mais classes.
Na prática
Na orientação a objetos, as classes abstratas servem apenas como modelo para classes concretas.
Portanto, não podem ser instanciadas. Elas são usadas em estruturas de herança. Com isso, outras
classes herdam seus membros. Uma classe abstrata pode conter ou não métodos abstratos.
Na Prática, você vai ver como a linguagem Java faz uso de palavras-chave para invocar uma classe
abstrata e como os desenvolvedores podem diferenciar uma classe genérica de uma abstrata.
Aponte a câmera para o
código e acesse o link do
conteúdo ou clique no
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/5990426e-57aa-4faa-8f8a-d41e327e997b/3a8c5a47-e948-46cd-92f5-4540d26cd460.png
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Classes abstratas
Acesse o vídeo e saiba um pouco mais sobre classes abstratas.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Conceitos – Classes abstratas: programação orientada a objetos
Neste artigo, você vai ver os conceitos de classes abstratas.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Java para iniciantes – Crie, compile e execute programas Java
rapidamente
Confira, na p. 239, o tópico "Classes abstratas, como usar e sua aplicação".
Conteúdo interativo disponível na plataforma de ensino!
Entenda de forma definitiva a diferença entre classes abstratas
e interfaces – POO
Assista ao vídeo e entenda as diferenças entre classes abstratas e interfaces na POO.
https://www.youtube.com/embed/RW6wRh3YT8M
https://www.devmedia.com.br/conceitos-classes-abstratas-programacao-orientada-a-objetos/18812
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.youtube.com/embed/zJml-dDGLsI