• Nenhum resultado encontrado

Exercícios: Encapsulamento, construtores e static

No documento Java e Orientação a Objetos (páginas 82-88)

1) Adicione o modificador de visibilidade (private, se necessário) para cada atributo e método da classe Funcionario. Tente criar um Funcionario no main e modificar ou ler um de seus atributos privados. O que acontece?

2) Crie os getters e setters necessários da sua classeFuncionario. Por exemplo:

class Funcionario {

private double salario;

// ...

public double getSalario() {

return this.salario; }

public void setSalario(double salario) {

this.salario = salario; }

}

Não copie e cole! Aproveite para praticar sintaxe. Logo passaremos a usar o Eclipse e aí sim teremos procedimentos mais simples para este tipo de tarefa.

3) Modifique suas classes que acessam e modificam atributos de um Funcionario para utilizar os getters e setters recém criados.

Por exemplo, onde você encontra:

f.salario = 100;

System.out.println(f.salario);

passa para:

f.setSalario(100);

System.out.println(f.getSalario());

4) Faça com que sua classe Funcionario possa receber, opcionalmente, o nome do Funcionario durante a criação do objeto. Utilize construtores para obter esse resultado.

Dica: utilize um construtor sem argumentos também, para o caso de a pessoa não querer passar o nome do

Funcionario. Seria algo como:

class Funcionario {

public Funcionario() {

// construtor sem argumentos

}

public Funcionario(String nome) {

// construtor que recebe o nome

} }

Por que você precisa do construtor sem argumentos para que a passagem do nome seja opcional?

5) (opcional) Adicione um atributo na classeFuncionariode tipointque se chama identificador. Esse identifi- cador deve ter um valor único para cada instância do tipoFuncionario. O primeiroFuncionarioinstanciado

tem identificador 1, o segundo 2, e assim por diante. Você deve utilizar os recursos aprendidos aqui para resolver esse problema.

Crie um getter para o identificador. Devemos ter um setter?

6) (opcional) Crie os getters e setters da sua classeEmpresae coloque seus atributos comoprivate. Lembre-se

de que não necessariamente todos os atributos devem ter getters e setters.

Por exemplo, na classeEmpresa, seria interessante ter um setter e getter para a sua array de funcionários?

Não seria mais interessante ter um método como este? class Empresa {

// ...

public Funcionario getFuncionario (int posicao) {

return this.empregados[posicao]; }

}

7) (opcional) Na classe Empresa, em vez de criar um array de tamanho fixo, receba como parâmetro no cons- trutor o tamanho do array deFuncionario.

Com esse construtor, o que acontece se tentarmos darnew Empresa()sem passar argumento algum? Por quê?

8) (opcional) Como garantir que datas como 31/2/2005 não sejam aceitas pela sua classe Data?

9) (opcional) Crie a classe PessoaFisica. Queremos ter a garantia de que pessoa física alguma tenha CPF

invalido, nem seja criadaPessoaFisicasem cpf inicial. (você não precisa escrever o algoritmo de validação de cpf, basta passar o cpf por um métodovalida(String x)....)

6.9 - Desafios

1) Porque esse código não compila? class Teste {

int x = 37;

public static void main(String [] args) { System.out.println(x);

}

}

2) Imagine que tenha uma classeFabricaDeCarroe quero garantir que só existe um objeto desse tipo em toda

a memória. Não existe uma palavra chave especial para isto em java, então teremos de fazer nossa classe de tal maneira que ela respeite essa nossa necessidade. Como fazer isso? (pesquise: singleton design pattern)

Orientação a Objetos – herança, reescrita e

polimorfismo

“O homem absurdo é aquele que nunca muda.” –Georges Clemenceau

Ao término desse capítulo, você será capaz de:

• dizer o que é herança e quando utilizá-la; • reutilizar código escrito anteriormente; • criar classes filhas e reescrever métodos; • usar todo o poder que o polimorfismo dá.

7.1 - Repetindo código?

Como toda empresa, nosso Banco possui funcionários. Vamos modelar a classeFuncionario:

class Funcionario { String nome; String cpf;

double salario;

// métodos devem vir aqui

}

Além de um funcionário comum, há também outros cargos, como os gerentes. Os gerentes guardam a mesma informação que um funcionário comum, mas possuem outras informações, além de ter funcionalidades um pouco diferentes. Um gerente no nosso banco possui também uma senha numérica que permite o acesso ao sistema interno do banco, além do número de funcionários que ele gerencia:

class Gerente { String nome; String cpf; double salario; int senha; int numeroDeFuncionariosGerenciados;

public boolean autentica(int senha) {

if (this.senha == senha) {

System.out.println("Acesso Permitido!");

return true; } else {

System.out.println("Acesso Negado!");

return false; }

}

// outros métodos

}

Precisamos mesmo de outra classe?

Poderíamos ter deixado a classeFuncionariomais genérica, mantendo nela senha de acesso, e o

número de funcionários gerenciados. Caso o funcionário não fosse um gerente, deixaríamos estes atributos vazios.

Essa é uma possibilidade, porém podemos começar a ter muito atributos opcionais, e a classe ficaria estranha. E em relação aos métodos? A classeGerentetem o métodoautentica, que não

faz sentido existir em um funcionário que não é gerente.

Se tivéssemos um outro tipo de funcionário que tem características diferentes do funcionário comum, preci- saríamos criar uma outra classe e copiar o código novamente!

Além disso, se um dia precisarmos adicionar uma nova informação para todos os funcionários, precisaremos passar por todas as classes de funcionário e adicionar esse atributo. O problema acontece novamente por não centralizarmos as informações principais do funcionário em um único lugar!

Existe um jeito, em Java, de relacionarmos uma classe de tal maneira que uma delas herda tudo que a outra tem. Isto é uma relação de classe mãe e classe filha. No nosso caso, gostaríamos de fazer com que oGerente

tivesse tudo que umFuncionariotem, gostaríamos que ela fosse uma extensão deFuncionario. Fazemos isto

através da palavra chaveextends.

class Gerente extends Funcionario {

int senha;

int numeroDeFuncionariosGerenciados;

public boolean autentica(int senha) {

if (this.senha == senha) {

System.out.println("Acesso Permitido!");

return true; } else {

System.out.println("Acesso Negado!");

return false; }

}

// setter da senha omitido

}

Em todo momento que criarmos um objeto do tipoGerente, este objeto possuirá também os atributos defi-

nidos na classeFuncionario, pois umGerenteé umFuncionario:

class TestaGerente {

public static void main(String[] args) { Gerente gerente = new Gerente();

// podemos chamar metodos do Funcionario:

gerente.setNome("João da Silva");

// e tambem metodos do Gerente!

gerente.setSenha(4231); }

}

Dizemos que a classe Gerente herda todos os atributos e métodos da classe mãe, no nosso caso, a Funcionario. Para ser mais preciso, ela também herda os atributos e métodos privados, porém não conse- gue acessá-los diretamente.

Super e Sub classe

A nomenclatura mais encontrada é queFuncionario é a superclasse deGerente, eGerenteé a subclasse deFuncionario. Dizemos também que todoGerenteé umFuncionário. Outra forma é

dizer queFuncionarioé classe mãe deGerenteeGerenteé classe filha deFuncionario.

E se precisamos acessar os atributos que herdamos? Não gostaríamos de deixar os atributos de

Funcionario,public, pois dessa maneira qualquer um poderia alterar os atributos dos objetos deste tipo. Existe um outro modificador de acesso, oprotected, que fica entre oprivatee opublic. Um atributoprotectedsó

pode ser acessado (visível) pela própria classe e por suas subclasses (e mais algumas outras classes, mas veremos isso em outro capítulo).

class Funcionario {

protected String nome;

protected String cpf;

protected double salario;

// métodos devem vir aqui

}

Sempre usar protected?

Então porque usar private? Depois de um tempo programando orientado a objetos, você vai começar a sentir que nem sempre é uma boa idéia deixar que a classe filha acesse os atributos da classe mãe, pois isso quebra um pouco a idéia de que só aquela classe deveria manipular seus atributos. Essa é uma discussão um pouco mais avançada.

Além disso, não só as subclasses, mas também as outras classes, podem acessar os atributos

protected, que veremos mais a frente (mesmo pacote). Veja outras alternativas aoprotectedno exercício de discussão em sala de aula juntamente com o instrutor.

Da mesma maneira, podemos ter uma classeDiretor que estenda Gerentee a classe Presidente pode estender diretamente deFuncionario.

Fique claro que essa é uma decisão de negócio. Se Diretor vai estender de Gerente ou não, vai depender se, para você, Diretor é um Gerente.

Uma classe pode ter várias filhas, mas pode ter apenas uma mãe, é a chamada herança simples do java.

No documento Java e Orientação a Objetos (páginas 82-88)

Documentos relacionados