Você está na página 1de 19

Conceitos de OO – Classes Abstratas

Prof. Lincoln Faria


lfaria@unicarioca.edu.br
Aula de hoje

Classes abstratas

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 2


Classes abstratas

Quando estamos desenvolvendo um sistema


orientado a objetos, podemos encontrar código
que é comum a muitas classes. E nesse caso
usamos a herança onde criamos uma classe
base (a superclasse) para que outras classes
(as subclasses) herdem dela.
Entretanto, não é raro notarmos que não faz
sentido instanciamos objetos dessa superclasse.

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 3


Classes abstratas

Por exemplo, em um contexto de sala de aula onde


tenho uma hierarquia de classes em que as classe
Professor e a classe Aluno herdam da classe pessoa,
não faz sentido criar um objeto da classe Pessoa.

Nesse caso, o mais conveniente é estabelecer a


classe Pessoa como uma classe abstrata.
Prof. Lincoln Faria - lfaria@unicarioca.edu.br 4
Classes abstratas

Classes abstratas são classes para as quais


você nunca pretende criar objetos, pois não faz
sentido criar objetos de tais classes. Elas
apenas servem de base para outras classes em
hierarquias de herança,
As subclasses devem declarar as "partes
ausentes" para tornarem-se classes "concretas",
a partir das quais você pode instanciar objetos.

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 5


Classes abstratas

Mais especificamente, uma classe abstrata


declara atributos e comportamentos comuns das
várias classes em uma hierarquia de classes.
Uma classe abstrata contém um ou mais
métodos abstratos que as subclasses devem
sobrescrever (implementar de fato) se elas
precisarem ser concreta, assim sendo
designadas de classes concretas.

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 6


Classes abstratas

Declarando uma classe abstrata e métodos abstratos

Tais declarações são realizadas com a palavra-chave


abstract .

public abstract class Empregado { //classe abstrata

public abstract double ganhos(); //método abstrato

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 7


Classes abstratas

Métodos abstratos não fornecem


implementações. Uma classe que contém
métodos abstratos deve ser declarada como
uma classe abstrata mesmo se essa classe
contiver alguns métodos concretos (não
abstratos). Cada subclasse concreta de uma
superclasse abstrata também deve fornecer
implementações concretas de cada um dos
métodos abstratos da superclasse.

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 8


Classes abstratas

Utilizando classes abstratas para declarar variáveis


Embora não seja possível instanciar objetos
de superclasses abstratas, você verá mais
adiante que é possível utilizar superclasses
abstratas para declarar variáveis que podem
conter referências a objetos de qualquer classe
concreta derivados dessas superclasses
abstratas.
Os programas em geral utilizam essas variáveis
para manipular objetos de subclasse
polimorficamente.
Prof. Lincoln Faria - lfaria@unicarioca.edu.br 9
Classes abstratas

Diagrama de
Exemplo: classes em UML

hierarquia de
herança
Empregado

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 10


Classes abstratas
public abstract class Empregado {
private String primeiroNome;
private String ultimoNome;
private String numeroPIS;

public Empregado(String primeiroNome, String ultimoNome, String numeroPIS) {


super();
this.primeiroNome = primeiroNome;
this.ultimoNome = ultimoNome;
this.numeroPIS = numeroPIS;
}
public String getPrimeiroNome() { Classe abstrata
return primeiroNome;
}
public void setPrimeiroNome(String primeiroNome) {
this.primeiroNome = primeiroNome;
}
public String getUltimoNome() {
return ultimoNome;
}
public void setUltimoNome(String ultimoNome) { Método sobrescrito
this.ultimoNome = ultimoNome;
}
public String getNumeroPIS() {
return numeroPIS;
}
public void setNumeroPIS(String numeroPIS) {
this.numeroPIS = numeroPIS;
}

@Override
public String toString()
{
return String.format( "%s %s\nNúmero do PIS: %s",
getPrimeiroNome(), getUltimoNome(), getNumeroPIS() );
}
Método abstrato
public abstract double ganhos();

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 11


Classes abstratas

public class EmpregadoComissao extends Empregado {

private double vendasSemanais; //em Reais


private double taxaComissao;
//construtor
public EmpregadoComissao(String primeiroNome, String ultimoNome,
String numeroPIS, double vendasSemanais, double taxaComissao) {
super(primeiroNome, ultimoNome, numeroPIS);
this.vendasSemanais = vendasSemanais;
this.taxaComissao = taxaComissao; Classe
}
public double getVendasSemanais() { concreta
return vendasSemanais;
}
public void setVendasSemanais(double vendasSemanais) {
this.vendasSemanais = ( vendasSemanais < 0.0 ) ? 0.0 : vendasSemanais;
}
public double getTaxaComissao() {
return taxaComissao;
}
public void setTaxaComissao(double taxaComissao) {
this.taxaComissao = ( taxaComissao > 0.0 && taxaComissao < 1.0 ) ? taxaComissao : 0.0;;
}
// retorna a representação Stringdo objeto EmpregadoComissao
@Override // indica que esse método sobrescreve um método de superclasse
public String toString(){
return String.format( "%s: %s\n%s: $%,.2f; %s: %.2f" ,
"Empregado comissionado", super.toString(),
"Vendas semanais", getVendasSemanais(),
"taxa de comissão" , getTaxaComissao());
}
// calcula os ganhos Implementação do
public double ganhos( ){ método ganhos()
return getTaxaComissao()*getVendasSemanais();
}
}
Prof. Lincoln Faria - lfaria@unicarioca.edu.br 12
Classes abstratas

public class EmpregadoComissaoMaisSalBase extends EmpregadoComissao {

private double salarioBase; //salário base por semana

public EmpregadoComissaoMaisSalBase(String primeiroNome, String ultimoNome,


String numeroPIS, double vendasSemanais, double taxaComissao, double
salarioBase) {
super(primeiroNome, ultimoNome, numeroPIS, vendasSemanais, taxaComissao);
setSalarioBase(salarioBase);
}

public double getSalarioBase() {


return salarioBase; Classe
} concreta
public void setSalarioBase(double salarioBase) {
this.salarioBase = (salarioBase < 0.0) ? 0.0:salarioBase;
}
@Override
public String toString(){
return String.format( "%s %s; %s: $%,.2f", "Empregado com salário base" ,
super.toString() , "salário base" , getSalarioBase());
}
// calcula os ganhos
@Override // indica que esse método sobrescreve
public double ganhos() {
return getSalarioBase() + super.ganhos(); Implementação do
} método ganhos()
}
Prof. Lincoln Faria - lfaria@unicarioca.edu.br 13
Classes abstratas
public class Aplicativo2 {
public static void main(String[] args) {
// Empregado empregado=new Empregado("Pedro", "Silva", "201136"); Não pode, classe abstrata
// Empregado empregado=new EmpregadoAssalariado("Pedro", "Silva", "201136", 2145.17);
EmpregadoAssalariado empregadoAssalariado =
new EmpregadoAssalariado( "John", "Smith", "111-11-1111", 800.00 );
EmpregadoHorista empregadoHorista = Classe de testes
new EmpregadoHorista( "Karen", "Price", "222-22-2222", 16.75, 40 );
EmpregadoComissao empregadoComissao = das classes
new EmpregadoComissao(
"Sue", "Jones", "333-33-3333", 10000, .06 );
EmpregadoComissaoMaisSalBase empregadoComissaoMaisSalBase =
new EmpregadoComissaoMaisSalBase(
"Bob", "Lewis", "444-44-4444", 5000, .04, 300 );
System.out.println( "Empregados processados individualmente:\n" );
System.out.printf( "%s\n%s: $%,.2f\n\n",empregadoAssalariado, "earned", empregadoAssalariado.ganhos() );
System.out.printf( "%s\n%s: $%,.2f\n\n",empregadoHorista, "earned", empregadoHorista.ganhos() );
System.out.printf( "%s\n%s: $%,.2f\n\n",empregadoComissao, "earned", empregadoComissao.ganhos() );
System.out.printf( "%s\n%s: $%,.2f\n\n",empregadoComissaoMaisSalBase,"earned",
empregadoComissaoMaisSalBase.ganhos() );
// cria array de empregado de 4 elementos
Empregado[] empregados = new Empregado[ 4 ]; //apenas declara uma variável vetor do tipo Empregado
// inicializa array com empregados
empregados[ 0 ] = empregadoAssalariado;
empregados[ 1 ] = empregadoHorista;
empregados[ 2 ] = empregadoComissao;
empregados[ 3 ] = empregadoComissaoMaisSalBase;

System.out.println( "Empregados processados poliformicamente:\n" );


// genericamente processa cada elemento no array de empregrados
System.out.printf("%s", empregados[0]);
System.out.printf("Valor ganho $%,.2f\n\n", empregados[0].ganhos() );
System.out.println( empregados[1]);
System.out.printf("Valor ganho $%,.2f\n\n", empregados[1].ganhos() );
System.out.println( empregados[2]);
System.out.printf("Valor ganho $%,.2f\n\n", empregados[2].ganhos() );
System.out.println( empregados[3]);
System.out.printf("Valor ganho $%,.2f\n\n", empregados[3].ganhos() );
}
}
Prof. Lincoln Faria - lfaria@unicarioca.edu.br 14
Classes abstratas

Por que não é possível instância um objeto


de uma classe abstrata, ou seja, por que a
linguagem Java não permite isso?

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 15


Classes abstratas

Por que não é possível instância um objeto


de uma classe abstrata, ou seja, por que a
linguagem Java não permite isso?

Resp.:
Pelo fato de uma classe abstrata possui métodos
abstratos (pelo menos um), teríamos um problema se tais
métodos (ou tal método) fossem invocado através de um
objeto criado dessa classe, pois método abstrato não tem
implementação e por isso não faz nada.

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 16


Classes abstratas

Por que, ao invés de declararmos um


método abstrato (sem implementação) em
uma superclasse abstrata, não
implementamos diretamente esse método
nas subclasses, sem tal declaração na
superclasse?

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 17


Classes abstratas

Por que, ao invés de declararmos um


método abstrato (sem implementação) em
uma superclasse abstrata, não
implementamos diretamente esse método
nas subclasses, sem tal declaração na
superclasse?
Resp.:
Além de forçamos a implementação desses métodos nas
subclasses, perderíamos o polimorfismo quando usamos
uma variável da superclasse para guardar uma referência
de objetos das subclasses.
Prof. Lincoln Faria - lfaria@unicarioca.edu.br 18
Considerações finais

Prof. Lincoln Faria - lfaria@unicarioca.edu.br 19