Você está na página 1de 39

Orientao a Objetos

com C#
Antonio Lopes Jr

Programao Orientada a Objetos

Sumrio
1

Introduo ............................................................................................................................... 3

Orientao a Objetos ............................................................................................................... 4

2.1

Objetos ............................................................................................................................. 4

2.2

Classe em C#..................................................................................................................... 5

2.3

Criando e Utilizando Classes ............................................................................................ 6

2.4

Mtodos ........................................................................................................................... 6

2.5

Mtodos com Retorno ..................................................................................................... 7

2.6

Mtodo Transfere ............................................................................................................ 8

2.7

Check Point ....................................................................................................................... 8

2.8

Testando ........................................................................................................................... 9

2.9

Exerccio ......................................................................................................................... 10

Modificadores de Acesso....................................................................................................... 10
3.1

Controlando o Acesso .................................................................................................... 10

3.2

Encapsulamento ............................................................................................................. 11

3.3

Getters e Setters ............................................................................................................ 12

3.4

Check Point ..................................................................................................................... 14

3.5

Testando ......................................................................................................................... 15

3.6

Exerccio ......................................................................................................................... 15

Construtores .......................................................................................................................... 16
4.1

Necessidade de Construtores ........................................................................................ 17

4.2

Mltiplos Construtores .................................................................................................. 17

4.3

Check Point ..................................................................................................................... 18

4.4

Testando ......................................................................................................................... 19

Herana .................................................................................................................................. 20
5.1

Exerccio ......................................................................................................................... 22

5.2

Sobrescrevendo Mtodos .............................................................................................. 22

5.3

Sobrecarregando Mtodos ............................................................................................ 24

5.4

Check Point ..................................................................................................................... 24

5.5

Testando ......................................................................................................................... 26

5.6

Exerccio ......................................................................................................................... 27

5.7

Polimorfismo .................................................................................................................. 27

Classes Abstratas ................................................................................................................... 28


6.1

Mtodos e Propriedades Abstratas ............................................................................... 29

6.2

Check Point ..................................................................................................................... 30

6.3

Exerccio ......................................................................................................................... 31

Interfaces ............................................................................................................................... 31
7.1

Check Point ..................................................................................................................... 33

7.2

Exerccio ......................................................................................................................... 34

Excees e Controle de Erros ................................................................................................ 34


8.1

Criando e Lanando uma Exceo .................................................................................. 35

8.2

Check Point ..................................................................................................................... 36

8.3

Testando ......................................................................................................................... 37

8.4

Exerccio ......................................................................................................................... 38

Referncias Bibliogrficas ...................................................................................................... 38

1 INTRODUO
C# uma linguagem de programao simples, moderna, orientada a objetos e type-safe. C# tem
sua origem na famlia C de linguagens e bem similar com as linguagens C, C++ e Java.
A linguagem C# oferece uma srie de recursos que nos ajudam a construir aplicaes robustas:
Garbage Collection gerencia memria de objetos, liberando-as quando necessrio; Exception
Handling fornece uma abordagem estruturada para tratamento de erros; e Type-Safe torna
impossvel acessar objetos no inicializados e sem tipagem.
Assim como o Java, o C# tambm utiliza o conceito de mquina virtual, onde existe, entre o
sistema operacional e a aplicao, uma camada extra responsvel por traduzir o que a sua
aplicao deseja fazer para as respectivas chamadas do sistema operacional onde ela est
rodando no momento.

Figura 1 - Ilustrao da arquitetura .Net e a mquina virtual.

A linguagem C# sempre conversa com a mquina virtual, neste caso, a Common Language
Runtime (CLR). A CLR o ambiente de execuo para todas as linguagens .Net, no apenas para
o C#. Como a CLR trabalha com diversas linguagens, os compiladores da linguagem .Net C#, C++,
VB , compilam os cdigos fontes em uma linguagem intermediria. Essa linguagem
intermediria o Common Intermadiate Language (CIL). Aps esse procedimento, a mquina
virtual CLR converte o cdigo .Net em cdigos nativos do sistema operacional.

Nos captulos seguintes, iremos abordar os principais conceitos da programao orientada a


objetos, tais como objeto, encapsulamento, herana, polimorfismo, aplicados na linguagem de
programao C#.

2 ORIENTAO A OBJETOS
Orientao a objetos uma maneira de programar que ajuda na organizao e resolve muitos
problemas enfrentados pela programao procedural.
Consideremos o clssico problema da validao de um CPF. Normalmente, temos um formulrio,
no qual recebemos essa informao, e depois temos que enviar esses caracteres para uma funo
que vai valid-lo, como no pseudocdigo abaixo:
Pseudocdigo
cpf = formulario.campo_cpf
valida(cpf)
Tabela 2.1 - Pseudocdigo que valida um cpf.

Algum te obriga a sempre validar esse CPF? O desenvolvedor pode, inmeras vezes, esquecer
de chamar esse validador. Ento, considerando a existncia de uma aplicao com 50 formulrios
e que precise validar em todos eles o CPF, em uma equipe de 3 programadores, quem fica
responsvel por essa validao? Todos!
A situao pode piorar na entrada de um novo desenvolvedor. Precisaramos avis-lo que sempre
devemos validar o CPF de um formulrio. nesse momento que nascem aqueles guias de
programao para o desenvolvedor que for entrar nesse projeto s vezes, um documento
enorme. Em outras palavras, todo desenvolvedor precisa ficar sabendo de uma quantidade
enorme de informaes, que, na maioria das vezes, no est realmente relacionado sua parte
no sistema, mas ele precisa ler tudo isso, resultando um entrave muito grande!
Imagine, agora, que voc precisa criar uma validao de idade. Aps criar essa validao, o
desenvolvedor dever aplica-la nos 50 formulrios. Que trabalho! E mesmo se considerarmos
que esse trabalho seja executado por um desenvolvedor experiente, ainda assim, pode ocorrer
falhas.
Ento, a programao orientada a objetos nos ajuda muito em organizar e escrever menos
cdigos, alm de concentrar as responsabilidades nos pontos corretos.

2.1 OBJETOS
Se consideramos um programa para um banco, bem fcil perceber que uma entidade
extremamente importante a entidade conta corrente. Neste caso, a nossa entidade, que
chamaremos de Conta, ser o nosso objeto.
Ento, nosso objeto Conta ter algumas caractersticas e funes a serem executadas.

As caractersticas do nosso objeto Conta so:

Nmero da conta corrente;


Nome do correntista;
Data de abertura da conta corrente;
Saldo da conta corrente;
Limite da conta corrente.

As funes que nosso objeto Conta ter como responsabilidades so:

Sacar;
Depositar;
Transferncia.
Por hora, nosso objeto Conta ser bem simples. No decorrer da apostila, iremos
adicionar mais funcionalidades.

Ento, o nosso objeto Conta ter o modelo de acordo com o apresentado na tabela abaixo.
Conta
Caractersticas
Nmero
Nome do Correntista
Data de Abertura
Saldo
Limite
Funes
Sacar
Depositar
Transferncia
Tabela 2.2 - Objeto Conta.

2.2 CLASSE EM C#
Vamos comear declarando apenas o que o nosso objeto Conta tem, e no o que ele faz. Ou
seja, vamos construir o objeto Conta em C# somente com suas caractersticas, e sem suas
funes.
Classes so os tipos mais importantes em C#. Uma classe uma estrutura de data que
combina estado (variveis) e aes (mtodos e eventos). Em C#, as classes so
declaradas utilizando a palavra reservada class.
A tabela 3 apresenta a declarao do nosso objeto Conta.

C#
class Conta
{
public string numero;
public string nome;
public DateTime dataAbertura;
public double saldo;
public double limite;
}
Tabela 2.3 - Declarao de classe Conta em C#.

2.3 CRIANDO E UTILIZANDO CLASSES


Para criar (construir, instanciar) qualquer objeto em C#, basta utilizar a palavra chave new e o
nome do objeto seguido de parnteses. A tabela 4 apresenta um trecho de cdigo que cria o
objeto Conta, adiciona nome e saldo para a Conta.
C#
Conta conta = new Conta();
conta.nome = "Ciclano de Tal";
conta.limite = 0;
conta.saldo = 1000;
Console.WriteLine($"Saldo atual {0}", conta.saldo);
Tabela 2.4 - Instanciando classe Conta.

2.4 MTODOS
No captulo 2.2, declaramos o que o nosso objeto Conta tem. Mas no declaramos o que o
objeto Conta faz. Para definirmos o comportamento do objeto Conta, utilizamos os mtodos.
Ento, definiremos dentro no objeto Conta as responsabilidades/funes de sacar e depositar.
A tabela 5 apresenta o trecho de cdigo do mtodo que saca um determinado valor de nosso
objeto Conta.
C#
public void Saca(double valor)
{
double novoSaldo = this.saldo = valor;
this.saldo = novoSaldo;
}
Tabela 2.5 - Mtodo "Saca".

No exemplo apresentado na tabela 5, a palavra reservada void significa que nosso


mtodo no ter retorno algum.
O valor a ser sacado enviado como parmetro toda vez que o mtodo Saca executado.
Ento, toda vez que utilizarmos o mtodo Saca, devemos informar o valor a ser sacado.
Observe o exemplo na tabela 6.

C#
Conta conta = new Conta();
conta.nome = "Ciclano de Tal";
conta.limite = 0;
conta.saldo = 1000;
conta.Saca(1250);
Console.WriteLine($"Saldo atual {0}", conta.saldo);
Tabela 2.6 - Utilizando o mtodo "Saca".

Repare que no exemplo apresentado na tabela 6, o saldo ficar abaixo do limite. Mais
frente evitaremos essa situao.
Da mesma forma que criamos o mtodo para sacar um valor de nosso objeto Conta, criaremos
o mtodo para depositar. A tabela 7 apresenta o trecho de cdigo com o mtodo que deposita
um determinado valor de nosso objeto Conta.
C#
public void Deposita(double valor)
{
double novoSaldo = this.saldo + valor;
this.saldo = novoSaldo;
}
Tabela 2.7 - Mtodo "Deposita".

O valor a ser depositado enviado como parmetro toda vez que o mtodo Deposita
executado. Ento, toda vez que utilizarmos o mtodo Deposita, devemos informar o valor a ser
depositado. Observe o exemplo na tabela 8.
C#
Conta conta = new Conta();
conta.nome = "Ciclano de Tal";
conta.limite = 0;
conta.saldo = 1000;
conta.Deposita(250);
Console.WriteLine($"Saldo atual {0}", conta.saldo);
Tabela 2.8 - Utilizando o mtodo "Deposita".

2.5 MTODOS COM RETORNO


Na definio de um mtodo, sempre necessrio especificar o que o mtodo retorna. Mesmo
quando no h retorno, como nos exemplos anteriores quando definimos os mtodos Saca e
Deposita especificando o retorno igual a void.
Iremos alterar o retorno do mtodo Saca. Ento, o mtodo Saca retornar verdadeiro ou
falso, onde, verdadeiro indica que o saque foi efetuado com sucesso e falso indica que no foi
possvel efetuar o saque por falta de limite.

C#
public bool Saca(double valor)
{
if (valor > (this.saldo + this.limite))
{
return false;
}
else
{
double novoSaldo = this.saldo = valor;
this.saldo = novoSaldo;
return true;
}
}
Tabela 2.9 - Mtodo "Saca".

2.6 MTODO TRANSFERE


Como ltimo passo e para finalizarmos o comportamento inicialmente definido para nosso
objeto Conta, precisamos criar o mtodo que transfere um valor de uma conta para outra.
Na tabela 10, o trecho de cdigo apresentado o mtodo Transfere, que recebe como
parmetro o Conta de destino e o valor da transferncia.
C#
public void Transfere(Conta destino, double valor)
{
destino.saldo = valor;
this.saldo = this.saldo - valor;
}
Tabela 2.10 - Mtodo "Transfere".

2.7 CHECK POINT


Aps definirmos nosso objeto Conta e os mtodos Saca, Deposita e Transfere, nosso
objeto Conta dever ser igual ao apresentado na tabela 11.
C#
class Conta
{
public string numero;
public string nome;
public DateTime dataAbertura;
public double saldo;
public double limite;
public bool Saca(double valor)
{
if (valor > (this.saldo + this.limite))
{
return false;
}
else
{

double novoSaldo = this.saldo = valor;


this.saldo = novoSaldo;
return true;
}
}
public void Deposita(double valor)
{
double novoSaldo = this.saldo + valor;
this.saldo = novoSaldo;
}
public void Transfere(Conta destino, double valor)
{
destino.saldo = valor;
this.saldo = this.saldo - valor;
}
}
Tabela 2.11 - Objeto Conta.

2.8 TESTANDO
Vamos realizar um teste para validar as caractersticas e comportamentos que desenvolvemos
para nosso objeto Conta.
Na classe Program, dentro no mtodo esttico Main, vamos executar o trecho de cdigo
disponvel na tabela 12.
C#
class Program
{
static void Main(string[] args)
{
Conta contaDoCiclano = new Conta();
contaDoCiclano.nome = "Ciclano de Tal";
contaDoCiclano.limite = 500;
contaDoCiclano.Deposita(250);
contaDoCiclano.Deposita(250);
Conta contaDoFulano = new Conta();
contaDoFulano.nome = "Fulano de Tal";
contaDoFulano.Deposita(1000);
contaDoFulano.Transfere(contaDoCiclano, 500);
Console.WriteLine($"Saldo do {contaDoCiclano.nome}: {contaDoCiclano.saldo}");
Console.WriteLine($"Saldo do {contaDoFulano.nome}: {contaDoFulano.saldo}");
}
}
Tabela 2.12 - Testando o objeto Conta.

Qual ser o resultado do teste executado utilizando o trecho de cdigo disponvel na tabela 12?

2.9 EXERCCIO
O cdigo do mtodo Transfere no est legal. O que acha de melhorarmos? Mos obra.

3 MODIFICADORES DE ACESSO
Todas as classes, mtodos e propriedades tem nveis de acessibilidade que controla se possvel
utiliz-las em outro cdigo dentro do projeto ou ainda, em outro projeto. Em C#, os principais
modificadores de acesso so: public; private; protected; e internal.
Modificador
private
public

protected
internal

O modificador private, quando aplicado um atributo ou mtodo indica


que os mesmos s podem ser acessados dentro da prpria classe.
O modificador public, quando aplicado um atributo, mtodo ou classe
indica que os mesmos podem ser acessados de qualquer lugar do
programa.
O modificador protected, quando aplicado um atributo ou mtodo indica
que os mesmos s podem ser acessados dentro da classe que a estende.
O modificador internal, quando aplicado a classes indica que o mesmo s
pode ser acessado dentro do mesmo projeto.

Tabela 3.1 - Modificadores de acesso.

Em C#, existem outros modificadores de acesso. No entanto, nesta apostila,


utilizaremos somente os apresentados na tabela 13.

3.1 CONTROLANDO O ACESSO


Apesar de termos melhorados consideravelmente o mtodo Saca, que evita sacar um valor
maior que o saldo mais o limite, gerando assim em um saldo negativo, at ento, nada garante
que o desenvolvedor sempre utilize o mtodo Saca. Observe o exemplo apresentado na tabela
abaixo.
C#
Conta contaDoCiclano = new Conta();
contaDoCiclano.limite = 100;
contaDoCiclano.saldo = -200; //saldo abaixo dos 100 limite
Tabela 3.2 - Negativando o saldo.

Como podemos observar na tabela 14, o trecho de cdigo no utiliza o mtodo Saca, e o saldo
acaba excedendo o limite disponvel. Como evitaramos isso? Para evitar esse problema em C#,
basta declararmos que os atributos no podem ser acessados de fora da classe. Ento, em nosso
objeto Conta, devemos alterar os modificadores de acesso dos atributos para private.
C#
class Conta
{
//...

private double saldo;


private double limite;
//...
Tabela 3.3 - Alterando o modificador de acesso.

Ao realizarmos a alterao apresentada na tabela 15, o cdigo apresentado na tabela 14


apresentar um erro, indicando que os atributos limite e saldo possuem um nvel de acesso
privado. Observe a figura 1 abaixo.

Figura 2 - Erro de acesso atributos privados.

muito comum, e faz todo sentido, que os atributos do objeto Conta sejam private e que os
mtodos sejam public. Desta forma, toda conversa de um objeto com outro feita por troca de
mensagens, isto , acessando seus mtodos. Utilizando essa abordagem, quando precisarmos
mudar como realizado um saque na nossa classe Conta, alteraramos somente o mtodo
Saca.

3.2 ENCAPSULAMENTO
Na programao orientada a objetos, encapsulamento significa separar o programa em partes, o
mais isolado possvel. A ideia tornar o software mais flexvel, fcil de modificar e de criar novas
implementaes. O encapsulamento serve para controlar o acesso aos atributos e mtodos de
uma classe. Para que o software seja suscetvel a mudanas no precisaremos mudar uma regra
de negcio em vrios lugares, mas sim em apenas um nico lugar, j que essa regra est
encapsulada.
C#
class Conta
{
//...
private double saldo;
public double Saldo
{
get { return this.saldo; }
}
private double limite;
public double Limite
{
get { return this.limite; }
}
//...
Tabela 3.4 - Encapsulando o limite e o saldo.

Observando o trecho de cdigo apresentado na tabela 16, o encapsulamento ocorre quando


preservamos o acesso aos campos limite e saldo. O acesso permitido atravs das
propriedades Limite (get) e Saldo (get).

Figura 3 - Mtodo getSaldo.

3.3 GETTERS E SETTERS


Para permitir o acesso aos atributos de maneira controlada, j que os mesmos so private, a
prtica mais comum criar propriedades com get e set, onde get retorna o valor do atributo e o
set muda o valor do atributo.
A conveno para essas propriedades de colocar a primeira letra em maiscula. Ou seja, para
a propriedade que encapsula o valor do atributo saldo, teramos Saldo e definiramos no
corpo da propriedade os get e set.
Se aplicarmos essa conveno ao nosso objeto Conta teramos algo semelhante ao
apresentado na tabela abaixo.
C#
class Conta
{
private string numero;
public string Numero
{
get { return this.numero; }
set { this.numero = value; }
}
private string nome;
public string Nome
{
get { return this.nome; }
set { this.nome = value; }
}

private DateTime dataAbertura;


public DateTime DataAbertura
{
get { return this.dataAbertura; }
set { this.dataAbertura = value; }
}
private double saldo;
public double Saldo
{
get { return this.saldo; }
}
private double limite;
public double Limite
{
get { return this.limite; }
set { this.limite = value; }
}
//...
Tabela 3.5 - Encapsulando os atributos da classe Conta.

uma m prtica criar uma classe e, logo em seguida, criar propriedades para todos seus
atributos. Voc s deve criar as propriedades se tiver a real necessidade. Repare que no trecho
de cdigo apresentado na tabela 17, na propriedade Saldo, o set no foi criado, j que
queremos que seja utilizado os mtodos Deposita e Saca.
Outro detalhe importante, que o get da propriedade AlgumaCoisa no necessariamente
retorna o valor de um atributo que chama algumaCoisa. Um exemplo desse cenrio o nosso
objeto Conta, onde o valor do saldo a soma do valor do atributo saldo mais o valor do
atributo limite. Poderamos sempre chamar as propriedades Limite + Saldo, mas isso
poderia gerar uma situao de termos que alterar todos os lugares que o saldo apresentado.
Ento, podemos encapsular esse calcular dentro do get da propriedade Saldo.
C#
class Conta
{
//...
private double saldo;
public double Saldo
{
get { return this.saldo + this.limite; }
}
//...
Tabela 3.6 - Encapsulando os atributos saldo e limite.

O trecho de cdigo apresentado na tabela 18 impossibilita a chamada do get da propriedade


Limite, pois ele no existe. E nem deve existir enquanto no houver essa necessidade. O get da
propriedade Saldo no devolve simplesmente o saldo, mas sim o que queremos que seja
mostrado como se fosse o saldo, ou seja, o saldo mais o limite. Utilizar getters e setters no s
ajuda voc a proteger os atributos do objeto, como tambm possibilita ter de mudar algo em um

s lugar. Isso o encapsulamento, pois esconde a maneira como os objetos guardam seus dados.
uma prtica muito importante.

3.4 CHECK POINT


Aps encapsularmos os atributos do nosso objeto Conta, nosso objeto Conta dever ser igual
ao apresentado na tabela 19.
C#
class Conta
{
private string numero;
public string Numero
{
get { return this.numero; }
set { this.numero = value; }
}
private string nome;
public string Nome
{
get { return this.nome; }
set { this.nome = value; }
}
private DateTime dataAbertura;
public DateTime DataAbertura
{
get { return this.dataAbertura; }
set { this.dataAbertura = value; }
}
private double limite;
public double Limite
{
set { this.limite = value; }
}
private double saldo;
public double Saldo
{
get { return this.saldo + this.limite; }
}
public bool Saca(double valor)
{
if (valor > (this.saldo + this.limite))
{
return false;
}
else
{
double novoSaldo = this.saldo - valor;
this.saldo = novoSaldo;
return true;
}

}
public void Deposita(double valor)
{
double novoSaldo = this.saldo + valor;
this.saldo = novoSaldo;
}
public void Transfere(Conta destino, double valor)
{
destino.saldo = destino.saldo + valor;
this.saldo = this.saldo - valor;
}
}
Tabela 3.7 - Objeto Conta.

3.5 TESTANDO
Vamos realizar um teste para validar as caractersticas e comportamentos que desenvolvemos
para nosso objeto Conta.
Na classe Program, dentro do mtodo esttico Main, vamos executar o trecho de cdigo
disponvel na tabela 20.
C#
class Program
{
static void Main(string[] args)
{
Conta contaDoCiclano = new Conta();
contaDoCiclano.Nome = "Ciclano de Tal";
contaDoCiclano.Deposita(250);
contaDoCiclano.Deposita(250);
Conta contaDoFulano = new Conta();
contaDoFulano.Nome = "Fulano de Tal";
contaDoFulano.Deposita(1000);
contaDoFulano.Transfere(contaDoCiclano, 500);
Console.WriteLine($"Saldo do {contaDoCiclano.Nome}: {contaDoCiclano.Saldo}");
Console.WriteLine($"Saldo do {contaDoFulano.Nome}: {contaDoFulano.Saldo}");
}
}
Tabela 3.8 - Testando o objeto Conta.

Qual ser o resultado do teste executado utilizando o trecho de cdigo disponvel na tabela 12?

3.6 EXERCCIO
O cdigo do mtodo Deposita no est legal. O que aconteceria se depositarmos um valor
negativo? Vamos melhorar o cdigo do mtodo Deposita. Mos obra.

4 CONSTRUTORES
Construtores so semelhantes a mtodos que implementam aes exigidas para inicializar um
novo objeto ou classe. A declarao de um construtor semelhante a declarao de um mtodo
sem retorno. O nome do construtor deve ter o mesmo nome da classe.
Na prtica, quando usamos a palavra new estamos construindo um objeto. Sempre quando o
new utilizado o construtor da classe executado. Vejamos um exemplo de como declaramos
um construtor.
C#
class Conta
{
//...
public Conta()
{
Console.WriteLine("Construindo uma conta.");
}
//...
Tabela 4.1 - Construtor do objeto conta.

Ento, quando criamos o trecho de cdigo apresentado na tabela 22, a mensagem Construindo
uma conta aparecer.
C#
Conta conta = new Conta();
Tabela 4.2 - Criando objeto conta.

Quando o desenvolvedor no declara um construtor em um objeto, o C# cria um


construtor padro. Esse construtor o construtor default, cujo no recebe nenhum
parmetro e no h implementao.
O interessante que um construtor pode receber um parmetro. Observe o exemplo
apresentado na tabela 23.
C#
class Conta
{
//...
public Conta(string nome)
{
this.nome = nome;
}
//...
Tabela 4.3 - Construtor com parmetro.

O construtor apresentado na tabela 23 recebe um nome como parmetro. Ento, ao criarmos


um objeto Conta, precisamos indicar o nome do cliente. Vejamos o exemplo abaixo.
C#

Conta conta1 = new Conta();


conta1.Nome = "Ciclano de Tal";
Conta conta2 = new Conta("Fulano de Tal");
Tabela 4.4 - Construtor com parmetro.

4.1 NECESSIDADE DE CONSTRUTORES


A razo da necessidade de um construtor bem simples. Se toda conta precisa de um titular,
vamos obrigar que todo o objeto conta tenha o titular. Ento, definimos um construtor que tenha
como parmetro o titular da conta.
O construtor se resume a isso! Dar possibilidades ou obrigar o desenvolvedor de uma classe a
passar parmetros para o objeto durante o processo de criao do mesmo.
Por exemplo, no podemos abrir um arquivo para leitura sem dizer qual o nome do arquivo
que desejamos ler. Portanto, nada mais natural que passar um parmetro representando o nome
de um arquivo na hora de criar um objeto do tipo de leitura de arquivo, e que isso seja obrigatrio.

4.2 MLTIPLOS CONSTRUTORES


Um construtor s executado durante a construo do objeto, isto , voc nunca conseguir
executar o construtor em um objeto j construdo. Porm, durante a construo de um objeto,
voc pode fazer com que um construtor chame outro. Vejamos o exemplo abaixo.
C#
class Conta
{
//...
public Conta()
{
this.limite = 100;
}
public Conta(string nome)
: this()
{
this.nome = nome;
}
public Conta(string numero, string nome)
: this(nome)
{
this.numero = numero;
}
//...
Tabela 4.5 - Mltiplos construtores.

Note que no trecho de cdigo apresentado na tabela 25 existem trs construtores. Um construtor
sem parmetro, um com um parmetro, e outro com dois parmetros. Quando o construtor com

dois parmetros executado, o mesmo executa o construtor com um parmetro e, por sua vez,
executa o construtor sem parmetro.

Figura 4 - Opes dos construtores.

4.3 CHECK POINT


Aps criarmos os construtores do nosso objeto Conta, nosso objeto Conta dever ser igual
ao apresentado na Tabela 4.6 Objeto Conta.
C#
public class Conta
{
private string numero;
public string Numero
{
get { return this.numero; }
set { this.numero = value; }
}
private string nome;
public string Nome
{
get { return this.nome; }
set { this.nome = value; }
}
private DateTime dataAbertura;
public DateTime DataAbertura
{
get { return this.dataAbertura; }
set { this.dataAbertura = value; }
}
private double limite;
public double Limite
{
set { this.limite = value; }
}
private double saldo;
public double Saldo
{
get { return this.saldo + this.limite; }
}
public Conta()
{
this.limite = 100;
}
public Conta(string nome)

: this()
{
this.nome = nome;
}
public Conta(string numero, string nome)
: this(nome)
{
this.numero = numero;
}
public bool Saca(double valor)
{
if (valor > (this.saldo + this.limite))
{
return false;
}
else
{
double novoSaldo = this.saldo - valor;
this.saldo = novoSaldo;
return true;
}
}
public void Deposita(double valor)
{
double novoSaldo = this.saldo + valor;
this.saldo = novoSaldo;
}
public void Transfere(Conta destino, double valor)
{
destino.saldo = destino.saldo + valor;
this.saldo = this.saldo - valor;
}
}
Tabela 4.6 Objeto Conta

4.4 TESTANDO
Vamos realizar um teste para validar as caractersticas e comportamentos que desenvolvemos
para nosso objeto Conta.
Na classe Program, dentro do mtodo esttico Main, vamos executar o trecho de cdigo
disponvel na tabela 27.
C#
class Program
{
static void Main(string[] args)
{
Conta contaDoCiclano = new Conta();
contaDoCiclano.Nome = "Ciclano de Tal";
contaDoCiclano.Deposita(250);
contaDoCiclano.Deposita(250);

Conta contaDoFulano = new Conta();


contaDoFulano.Nome = "Fulano de Tal";
contaDoFulano.Deposita(1000);
contaDoFulano.Transfere(contaDoCiclano, 500);
Console.WriteLine($"Saldo do {contaDoCiclano.Nome}: {contaDoCiclano.Saldo}");
Console.WriteLine($"Saldo do {contaDoFulano.Nome}: {contaDoFulano.Saldo}");
}
}
Tabela 4.7 - Testando o objeto Conta

Qual ser o resultado do teste executado utilizando o trecho de cdigo disponvel na Tabela 4.7
- Testando o objeto Conta?

5 HERANA
Em programao orientada a objetos, herana resume na habilidade em construir um novo
objeto baseado em um objeto j existente. Em essncia, herana permite estender as
caractersticas (atributos) e comportamentos (mtodos) de uma classe, com o objetivo principal
de reaproveitar essas caractersticas e comportamentos, sem a necessidade de defini-las
novamente.
Para exemplificar herana na prtica, vamos criar duas classes novas: Funcionrio e Gerente.
Como toda a empresa, nosso banco possui funcionrios. Vamos modelar a classe funcionrio.
C#
public class Funcionario
{
private string nome;
private string cpf;
private DateTime dataNascimento;
private DateTime dataAdmissao;
private double salario;
//...
}
Tabela 5.1 - Classe Funcionrio.

Alm de funcionrio comum, no banco, h tambm outros cargos, como por exemplo, os
gerentes. Os gerentes possuem as mesmas caractersticas que um funcionrio comum, mais
tambm possuem outras caractersticas adicionais, alm de ter funcionalidades diferentes. O
nosso Gerente tambm possui uma senha que permite o acesso ao sistema interno do banco,
alm do nmero de funcionrios subordinados. Vamos modelar nossa classe de Gerente.
C#
public class Gerente
{
private string nome;
private string cpf;
private DateTime dataNascimento;

private double salario;


private string senha;
private int numeroDeSubordinados;
public bool autentica(String senha)
{
if (this.senha.Equals(senha))
{
return true;
}
else
{
return false;
}
}
//...
}
Tabela 5.2 - Classe Gerente.

Se tivssemos um outro tipo de funcionrio com caractersticas diferentes do Funcionrio


comum, ou Gerente precisaramos criar uma outra classe e copiar o cdigo novamente. Alm
disso, se um dia precisssemos adicionar uma nova informao para todos os tipos de
funcionrios, precisaramos passar por todas as classes de funcionrio e adicionar essa nova
informao. O problema acontece novamente por no termos centralizado as informaes
principais do funcionrio em um nico lugar.
Em C#, existe uma forma relativamente simples de relacionarmos uma classe de tal maneira que
uma delas herda tudo que a outra tem. Isto uma relao de classe me e classe filha. No nosso
caso, gostaramos de fazer com que o Gerente tivesse tudo que um Funcionrio tem.
Gostaramos que a classe Gerente fosse uma extenso da classe Funcionrio. Fazemos isto
inserindo : aps a classe filha, seguido da classe me.
C#
public class Gerente : Funcionario
{
private string senha;
private int numeroDeSubordinados;
public bool autentica(String senha)
{
if (this.senha.Equals(senha))
{
return true;
}
else
{
return false;
}
}
//...
}
Tabela 5.3 - Herana de Funcionrio para Gerente.

Em todo momento que criarmos um objeto do tipo Gerente, este objeto possuir tambm os
atributos definidos na classe Funcionrio, pois um Gerente um Funcionrio.
C#
Gerente gerente = new Gerente();
//setNome est definido na classe Funcionrio
gerente.Nome = "Fulano de Tal";
//setSenha est definido na classe Gerente.
gerente.Senha
Tabela 5.4 - Instanciando a classe Gerente.

Dizemos que a classe Gerente herda todos os atributos e mtodos da classe me, no nosso
caso, a classe Funcionrio. Para ser mais preciso, ela tambm herda os atributos e mtodos
privados, porm no consegue acess-los diretamente. Para acessar um membro privado na filha
indiretamente, seria necessrio que a me expusesse um outro mtodo visvel que invocasse
esse atributo ou mtodo privado.

5.1 EXERCCIO
E se precisarmos acessar os atributos da classe que herdamos? No gostaramos de deixar os
atributos da classe Funcionrio expostos, pois dessa maneira qualquer um poderia alterar os
atributos dos objetos deste tipo. Qual o outro modificador de acesso que podemos utilizar para
resolver esse problema? Vamos alterar os modificadores de acesso dos atributos de nossa classe
Funcionrio, permitindo a visibilidade dos atributos nas subclasses.
Super e subclasse
Dizemos que Funcionrio a superclasse de Gerente e Gerente a subclasse de
Funcionrio. Tambm podemos dizer que Funcionrio a classe me de Gerente e
Gerente a classe filha de Funcionrio.

5.2 SOBRESCREVENDO MTODOS


Sobrescrever mtodos est diretamente relacionada orientao a objetos, mais
especificamente com a herana. Com a sobrescrita, conseguimos especializar os mtodos
herdados das superclasses, alterando o seu comportamento nas subclasses por um mais
especfico. A sobrescrita de mtodos consiste basicamente em criar um novo mtodo na classe
filha contendo a mesma assinatura e mesmo tipo de retorno do mtodo sobrescrito.
Para exemplificar o conceito de sobrescrita de mtodo, imagine que os funcionrios do banco
recebem uma bonificao todos os meses. Os funcionrios comuns recebem 10% do valor do
salrio. Os gerentes recebem 15% do valor do salrio.
Vamos ver como fica a classe Funcionrio.
C#
public class Funcionario
{
//...

public double Bonificacao


{
get { return this.salario * 0.10; }
}
//...
}
Tabela 5.5 Mtodo getBonificacao.

Se deixarmos a classe Gerente como est, a classe vai herdar o mtodo getBonificacao. Ou
seja, o percentual de bonificao ser de 10% ao invs de 15%, como, neste caso, deveria ser.
C#
Gerente gerente = new Gerente();
gerente.Salario = 500.0;
Console.WriteLine(gerente.Bonificacao);
Tabela 5.6 - Classe Gerente e a propriedade Bonificacao

O resultado do trecho de cdigo apresentado na Tabela 5.6 - Classe Gerente e a propriedade


Bonificacao ser 500. No queremos essa resposta, pois neste caso, o gerente deveria ter 750
de bnus ao invs de 500. Para adequar a classe Gerente, uma das opes seria criar uma nova
propriedade na classe Gerente, chamado, por exemplo, BonificacaoDoGerente. O problema
que teramos duas propriedades na classe Gerente, o que confundiria bastante.
Em C#, quando herdamos um mtodo, podemos alterar seu comportamento. Ou seja, podemos
reescrever (reescrever, sobrescrever, override) o mtodo herdado.
C#
public class Funcionario
{
//...
public virtual double Bonificacao
{
get { return this.salario * 0.10; }
}
//...
}
Tabela 5.7 - Sobrescrevendo a propriedade "Bonificacao"

C#
public class Gerente : Funcionario
{
//...
public override double Bonificacao
{
Get { return this.Salario * 0.15; }
}
//...
}
Tabela 5.8 - Sobrescrevendo a propriedade "Bonificacao"

Com o ajuste realizado em nossa classe Gerente, a bonificao do funcionrio Gerente fica
correta. Isto , se executarmos o mesmo trecho de cdigo apresentado na Tabela 5.6 - Classe
Gerente e a propriedade Bonificacao, o resultado ser de 750, no mais 500.

5.3 SOBRECARREGANDO MTODOS


Mtodos sobrecarregados so mtodos com o mesmo nome, mas com argumentos diferentes.
Com a sobrecarga, tambm conseguimos especializar os mtodos sobrecarregados, mas
diferente do que ocorre com a sobrescrita, no substitumos os mtodos herdados das
superclasses. Apenas criamos um novo mtodo, com o mesmo nome, mas parmetros diferentes.
C#
public class Funcionario
{
//...
public void setNome(String nome)
{
this.nome = nome;
}
public void setNome(String nome, String sobrenome)
{
this.nome = nome;
this.sobrenome = sobrenome;
}
//..
}
Tabela 5.9 - Sobrecarregando mtodos

Na Tabela 5.9 - Sobrecarregando mtodos, temos dois mtodos com o mesmo modificador de
acesso, retorno, nome, mas os parmetros so diferentes. Quando instanciamos uma classe
Gerente e utilizamos o mtodo setNome, a IDE nos fornece duas opes: setNome(String
nome) e setNome(String nome, String sobrenome).

Figura 5.1 Mtodo sobrecarregado setNome

5.4 CHECK POINT


Aps aplicarmos os conceitos de herana e sobrescrita nos objetos Funcionrio e Gerente,
as classes devem estar, respectivamente, iguais as apresentadas nas Tabela 5.10 - Classe
Funcionrio e Tabela 5.11 - Classe Gerente.
C#
public class Funcionario
{
private string nome;
private string sobrenome;
private string cpf;
private DateTime dataNascimento;
private DateTime dataAdmissao;
private double salario;

public string Nome


{
get { return this.nome; }
set { this.nome = value; }
}
public void setNome(String nome)
{
this.nome = nome;
}
public void setNome(String nome, String sobrenome)
{
this.nome = nome;
this.sobrenome = sobrenome;
}
public string Cpf
{
get { return this.cpf;}
set { this.cpf = value;}
}
public DateTime DataNascimento
{
get { return this.dataNascimento; }
set { this.dataNascimento = value; }
}
public DateTime DataAdmissao
{
get { return this.dataAdmissao; }
set { this.dataAdmissao = value; }
}
public double Salario
{
get { return this.salario; }
set { this.salario = value; }
}
public virtual double Bonificacao
{
get { return this.salario * 0.10; }
}
}
Tabela 5.10 - Classe Funcionrio

C#
public class Gerente : Funcionario
{
private string senha;
private int numeroDeSubordinados;
public string Senha
{
get { return this.senha; }
set { this.senha = value; }

}
public int NumeroDeSubordinados
{
get { return this.numeroDeSubordinados; }
set { this.numeroDeSubordinados = value; }
}
public bool autentica(String senha)
{
if (this.senha.Equals(senha))
{
return true;
}
else
{
return false;
}
}
public override double Bonificacao
{
get { return this.Salario * 0.15; }
}
}
Tabela 5.11 - Classe Gerente

5.5 TESTANDO
Vamos realizar um teste para validar a sobrescrita e sobrecarga que desenvolvemos em nossas
classes Funcionario e Gerente.
Na classe Program, dentro do mtodo esttico main, vamos executar o trecho de cdigo
disponvel na Tabela 5.12 - Testando a propriedade "Bonificacao".
C#
class Program
{
static void Main(string[] args)
{
Funcionario funcionario = new Funcionario();
funcionario.Nome = "Beltrano de Tal";
funcionario.Salario = 5000.0;
Gerente gerente = new Gerente();
gerente.Nome = "Fulano de Tal";
gerente.Salario = 5000.0;
Console.WriteLine($"Bonificao do funcionrio {funcionario.Nome}
{funcionario.Bonificacao}");
Console.WriteLine($"Bonificao do gerente {gerente.Nome}
{gerente.Bonificacao}");
}
}
Tabela 5.12 - Testando a propriedade "Bonificacao".

Qual ser o resultado do teste executado utilizando o trecho de cdigo disponvel na Tabela 5.12
- Testando a propriedade "Bonificacao".?

5.6 EXERCCIO
Suponhamos que agora, queremos mudar o clculo da bonificao. Ento, ao invs da
bonificao ter um acrscimo de 15% do salrio do gerente, o acrscimo passa a ser de 10% do
salrio, mais 15% do salrio, ou seja, salrio * 10% * 15%. Mos obra.

5.7 POLIMORFISMO
Polimorfismo o princpio pela qual duas ou mais classes derivadas de uma mesma superclasse
podem invocar propriedades ou mtodos que tem a mesma identificao e assinatura, mas
comportamentos diferentes, especializados para cada classe derivada.
Podemos dizer que uma classe chamada Vendedor e outra chamada Diretor podem ter como
base uma classe chamada Pessoa, com um mtodo chamado calculaVendas. Se este mtodo,
definido na classe base, se comportar de maneira diferente nas classes Vendedor e Diretor,
o mtodo ser considerado um mtodo polimrfico, ou seja, um mtodo de vrias formas.
C#
Gerente gerente = new Gerente();
Funcionario funcionario = gerente;
funcionario.Salario = 5000.0;
Console.WriteLine(gerente.Bonificacao);
Tabela 5.13 - Objeto polimrfico

Observe a Tabela 5.13 - Objeto polimrfico. A classe Funcionrio um objeto que pode ser
referenciado de vrias formas, ou seja, tanto pode receber a referncia de uma instncia de
Funcionrio quanto de Gerente. Ento, nosso funcionrio um Gerente e a bonificao
de 750.
Cuidado! Polimorfismo no quer dizer que o objeto fica se transformando. Muito pelo
contrrio, um objeto nasce de um tipo e morre daquele tipo. O que pode mudar a
forma como nos referimos a esse objeto.
Observe esse outro exemplo.
C#
class Program
{
static void Main(string[] args)
{
Gerente gerente = new Gerente();
gerente.Salario = 5000.0;
Imprime(gerente);

Funcionario funcionario = new Funcionario();


funcionario.Nome = "Ciclano de Tal";
funcionario.Salario = 5000.0;
}
static void Imprime(Funcionario funcionario)
{
Console.WriteLine($"{funcionario.GetType()} - Bonificao de {funcionario.Nome}
{funcionario.Bonificacao}");
}
}
Tabela 5.14 - Mtodo polimrfico

No trecho de cdigo apresentado na Tabela 5.14 - Mtodo polimrfico, no mtodo imprime,


conseguimos passar tanto um objeto Funcionrio quanto Gerente. A assinatura do mtodo
imprime recebe um objeto do tipo Funcionrio. Logo, um objeto do tipo Gerente tambm
pode ser utilizado como parmetro do mtodo, pois Gerente um Funcionrio.

6 CLASSES ABSTRATAS
As classes abstratas so classes que no podem ser instncias ou criadas. So classes feitas
especialmente para serem modelos para suas classes derivadas. As classes derivadas, em via de
regra, sobrescrevem os mtodos para realizar a implementao dos mesmos. As classes
derivadas das classes abstratas so conhecidas como classes concretas.
Para entender melhor classes abstratas, vamos imaginar que para o nosso sistema de banco, seja
inadmissvel que um objeto seja apenas do tipo Funcionrio. Ento, em nossa classe Funcionrio,
utilizaremos a palavra chave abstract para impedir que a classe seja instanciada. Observe na
Tabela 6.1 [Classe abstrata Funcionrio], como fica nossa classe Funcionrio.
C#
public abstract class Funcionario
{
protected string nome;
protected string sobrenome;
protected string cpf;
protected DateTime dataNascimento;
protected double salario;
//...
}
Tabela 6.1 [Classe abstrata Funcionrio]

Agora, se tentarmos instanciar a classe Funcionrio o Visual Studio acusar um erro. Assim como
se tentarmos compilar nossa aplicao. Observe as Figura 6.1 [Erro ao instanciar uma classe
abstrata] e Figura 6.2 [Em ao compilar a aplicao].

Figura 6.1 [Erro ao instanciar uma classe abstrata]

Figura 6.2 [Em ao compilar a aplicao]

6.1 MTODOS E PROPRIEDADES ABSTRATAS


Mtodos ou propriedades abstratos so mtodos que no possuem implementao. Os mtodos
abstratos definidos em uma classe abstrata devem ser obrigatoriamente implementados na
classe concreta.
No nosso sistema de banco, se a propriedade Bonificacao no fosse reescrita, ela seria herdada
da classe me, fazendo com que devolvesse o salrio mais 20%. Levando em considerao que
cada funcionrio em nosso sistema tem uma regra totalmente diferente para ser bonificado, no
faz sentido ter essa propriedade na classe Funcionrio. para esta situao que existe os
mtodos e propriedades abstratas, ou seja, podemos forar que um determinado mtodo ou
propriedade seja sempre reescrito nas classes filhas.
Vamos transformar nossa propriedade Bonificacao em abstrato. Para isso, tambm iremos
utilizar a palavra chave abstract, mas desta vez, na assinatura da propriedade ao invs da
assinatura da classe.
C#
public abstract class Funcionario
{
//...
public abstract double Bonificacao { get; }
}
Figura 6.3 [Propriedade abstrata Bonificacao]

Observe que na Figura 6.3 [Propriedade abstrata Bonificacao], a propriedade Bonficacao no


existe corpo, isto , no existe implementao de uma regra de negcio. Esta implementao
ser desenvolvida nas classes concretas, que herdam a classe Funcionrio.

6.2 CHECK POINT


Aps transformarmos nossa classe Funcionrio em classe abstrata e o mtodo getBonficacao em
mtodo abstrato, nossas classes Funcionrio e Gerente devem ser semelhantes as apresentadas
nas Figura 6.4 [Classe Funcionrio] e Figura 6.5 [Classe Gerente].
C#
public abstract class Funcionario
{
protected string nome;
protected string sobrenome;
protected string cpf;
protected DateTime dataNascimento;
protected double salario;
public string Nome
{
get { return this.nome; }
set { this.nome = value; }
}
public void setNome(String nome)
{
this.nome = nome;
}
public void setNome(String nome, String sobrenome)
{
this.nome = nome;
this.sobrenome = sobrenome;
}
public string Cpf
{
get { return this.cpf;}
set { this.cpf = value;}
}
public DateTime DataNascimento
{
get { return this.dataNascimento; }
set { this.dataNascimento = value; }
}
public double Salario
{
get { return this.salario; }
set { this.salario = value; }
}
public abstract double Bonificacao { get; }
}
Figura 6.4 [Classe Funcionrio]

C#
public class Gerente : Funcionario
{

private string senha;


private int numeroDeSubordinados;
public string Senha
{
get { return this.senha; }
set { this.senha = value; }
}
public int NumeroDeSubordinados
{
get { return this.numeroDeSubordinados; }
set { this.numeroDeSubordinados = value; }
}
public bool autentica(String senha)
{
if (this.senha.Equals(senha))
{
return true;
}
else
{
return false;
}
}
public override double Bonificacao
{
get { return this.Salario * 0.15; }
}
}
Figura 6.5 [Classe Gerente]

6.3 EXERCCIO
Suponhamos que agora, criamos mais funes em nosso banco. Ento vamos criar trs novas
classes: Secretrio, Atendente e Diretor. Mos obra.

7 INTERFACES
As interfaces so teis porque elas estabelecem contratos. Se uma classe implementar uma
interface voc vai poder referenciar instancias da classe pela interface tendo somente acesso aos
membros definidos na interface. Isso significa basicamente, que voc garante que a classe
apresentar um certo comportamento sem que se saiba a priori como esse comportamento
implementado.
Vamos imaginar que em nosso sistema de banco precisamos delimitar o mtodo Autentica, que
fornece acesso ao sistema interno do banco, somente para os funcionrios do tipo Gerente e
Diretor. Os funcionrios do tipo Secretrio e Atendente no devem ter acesso ao sistema interno
do banco. Poderamos definir o mtodo Autentica na classe abstrata Funcionrio, mas iramos

nos deparar que os funcionrios do tipo Secretrio e Atendente precisariam implementar esse
mtodo sem a necessidade, pois os mesmos no devem ter acesso ao sistema interno do banco.
Uma forma simples de resolver a questo descrita no pargrafo seguinte implementando uma
interface. Em C#, uma interface semelhante a uma classe e utilizamos a palavra chave interface.
Vejamos o exemplo apresentado na Figura 7.1 [Interface IAutenticavel].
C#
public interface IAutenticavel
{
bool Autentica(string senha);
}
Figura 7.1 [Interface IAutenticavel]

A ideia da interface IAutenticavel sugerir que todo objeto que necessite autenticar no sistema
interno do banco, precisa ser autenticvel, isto , precisa implementar a interface IAutenticavel.
No nosso sistema de banco, as classes Gerente e Diretor precisam implementar essa interface.
C#
public class Gerente : Funcionario, IAutenticavel
{
//...
public bool Autentica(string senha)
{
return this.senha.Equals(senha);
}
//...
}
Tabela 7.1 [Classe Gerente implementando a interface Autenticvel]

C#
public class Diretor : Funcionario, IAutenticavel
{
//...
public bool Autentica(string senha)
{
return this.senha.Equals(senha);
}
//...
}
Tabela 7.2 [Classe Diretor implementando a interface IAutenticavel]

Agora, com os funcionrios do tipo Gerente e Diretor implementando a interface IAutenticavel,


podemos afirmar que os mesmos so autenticveis e possuem uma forma de acesso ao sistema
interno.

7.1 CHECK POINT


Aps a definio da interface IAutenticvel, nossa interface e nossas classes devem estar
semelhantes as apresentadas nas tabelas Tabela 7.3 [Interface IAutenticavel], Tabela 7.4 [Classe
Gerente] e Tabela 7.5 [Classe Diretor].
C#
public interface IAutenticavel
{
bool Autentica(string senha);
}
Tabela 7.3 [Interface IAutenticavel]

C#
public class Gerente : Funcionario, IAutenticavel
{
private string senha;
private int numeroDeSubordinados;
public string Senha
{
get { return this.senha; }
set { this.senha = value; }
}
public int NumeroDeSubordinados
{
get { return this.numeroDeSubordinados; }
set { this.numeroDeSubordinados = value; }
}
public bool Autentica(string senha)
{
return this.senha.Equals(senha);
}
public override double Bonificacao
{
get { return this.Salario * 0.15; }
}
}
Tabela 7.4 [Classe Gerente]

C#
public class Diretor : Funcionario, IAutenticavel
{
private string senha;
public string Senha
{
get { return senha; }
set { senha = value; }
}
public override double Bonificacao
{

get { return this.Salario * 0.25; }


}
public bool Autentica(string senha)
{
return this.senha.Equals(senha);
}
}
Tabela 7.5 [Classe Diretor]

7.2 EXERCCIO
Suponhamos que agora, criamos mais funes em nosso banco. Ento vamos criar trs novas
classes: Presidente, Coordenador, Estagirio. Mos obra.

8 EXCEES E CONTROLE DE ERROS


Uma exception, ou exceptional event, um problema que ocorre durante a execuo de um
programa. Quando uma exceo ocorre, o fluxo normal do programa interrompido e a
aplicao termina inesperadamente, o que no recomendado, por isso, uma exceo deve ser
tratada.
Para entender melhor, vamos realizar um exemplo.
C#
class Program
{
static void Main(string[] args)
{
Funcionario[] funcionarios = new Funcionario[2];
for (int i = 0; i < 10; i++)
{
Funcionario func = funcionarios[i];
}
}
}
Tabela 8.1 [Exceo IndexOutOfRangeException]

Se observarmos o exemplo da Tabela 8.1 [Exceo IndexOutOfRangeException] podemos ver um


lao de funcionrio com tamanho igual a 2. Vemos tambm um lao de repetio que percorre o
lao de funcionrio por 10 vezes. No entanto, se o lao de funcionrio tem o tamanho igual a 2,
o que ocorreria se acessarmos o funcionrio na posio 5, 7 ou 9?

Figura 8.1 [Exceo apresentada pelo compilador]

A Figura 8.1 [Exceo apresentada pelo compilador] apresenta a exceo lanada pelo
compilador. No entanto, neste exemplo no existe nenhum tratamento da exceo.

8.1 CRIANDO E LANANDO UMA EXCEO


Vamos criar uma exceo para utilizarmos em nossa classe Conta. Comearemos definindo a
classe SaldoInsuficienteException. Observe o trecho do cdigo apresentado na Tabela 8.2 [Classe
SaldoInsuficienteException].
C#
public class SaldoInsuficienteException : Exception
{
public SaldoInsuficienteException(string message)
: base(message)
{
}
}
Tabela 8.2 [Classe SaldoInsuficienteException]

Agora, em nossa classe Conta, vamos ajustar o mtodo Saca. Observe o trecho de cdigo da
Tabela 8.3 [Lanando exceo].
C#
public bool Saca(double valor)
{
if (valor > (this.saldo + this.limite))
{
throw new SaldoInsuficienteException("Saldo Insuficiente!");
}
else
{

double novoSaldo = this.saldo - valor;


this.saldo = novoSaldo;
return true;
}
}
Tabela 8.3 [Lanando exceo]

8.2 CHECK POINT


Aps a definio de nossa prpria exceo SaldoInsuficienteException e alterao do mtodo
Saca em nossa classe Conta, a classe Conta deve estar semelhante a apresentada na Tabela 8.4
[Classe Conta].
C#
public class Conta
{
private string numero;
public string Numero
{
get { return this.numero; }
set { this.numero = value; }
}
private string nome;
public string Nome
{
get { return this.nome; }
set { this.nome = value; }
}
private DateTime dataAbertura;
public DateTime DataAbertura
{
get { return this.dataAbertura; }
set { this.dataAbertura = value; }
}
private double limite;
public double Limite
{
set { this.limite = value; }
}
private double saldo;
public double Saldo
{
get { return this.saldo + this.limite; }
}
public Conta()
{
this.limite = 100;
}
public Conta(string nome)
: this()
{

this.nome = nome;
}
public Conta(string numero, string nome)
: this(nome)
{
this.numero = numero;
}
public bool Saca(double valor)
{
if (valor > (this.saldo + this.limite))
{
throw new SaldoInsuficienteException("Saldo Insuficiente!");
}
else
{
double novoSaldo = this.saldo - valor;
this.saldo = novoSaldo;
return true;
}
}
public void Deposita(double valor)
{
double novoSaldo = this.saldo + valor;
this.saldo = novoSaldo;
}
public void Transfere(Conta destino, double valor)
{
destino.saldo = destino.saldo + valor;
this.saldo = this.saldo - valor;
}
}
Tabela 8.4 [Classe Conta]

8.3 TESTANDO
Com a definio de nossa prpria exceo e a alterao do nosso mtodo saca, como fazemos
para evitar que nosso programa pare inesperadamente? Temos que tratar as excees. Vamos
fazer esse tratamento na nossa classe Program dentro do mtodo Main.
C#
static void Main(string[] args)
{
Conta conta = new Conta();
conta.Limite = 500;
try
{
conta.Saca(800);
}
catch (SaldoInsuficienteException e)
{
Console.WriteLine(e.Message);
}

Console.ReadLine();
}
Tabela 8.5 [Tratando a exceo SaldoInsuficienteException]

8.4 EXERCCIO
Vamos alterar o mtodo Saca para lanar uma exceo quando o parmetro valor for zero ou
nulo.

9 REFERNCIAS BIBLIOGRFICAS
TROELSEN, ANDREW. Pro C# 5.0 and the .NET 4.5 Framework. Editora Apress, Sexta Edio, 2012,
1560 pginas.
Windows
Dev
Center.
C#
Language
Specification
5.0.
Disponvel
em
<http://www.microsoft.com/en-us/download/details.aspx?id=7029>. Acesso em 03 de maio de
2015.
DEV CENTER. Introduction to Generics (C# Programming Guide). Disponvel em
<https://msdn.microsoft.com/en-us/library/0x6a29h6(v=vs.140).aspx>. Acesso em 04 de junho
de 2015.
DEV CENTER. Introduo a consultas LINQ (C#). Disponvel em <https://msdn.microsoft.com/ptbr/library/bb397906.aspx>. Acesso em 27 de outubro de 2015.
DEV CENTER. Query Sintax and Method Syntax in LINQ (C#).
Disponvel em
<https://msdn.microsoft.com/ptbr/library/bb397947.aspx?sentenceGuid=f8585a09920d6fd422c4db97d8e14b94#mt5>. Acesso
em 27 de outubro de 2015.
DEV CENTER. 101 LINQ Samples. Disponvel em <https://code.msdn.microsoft.com/101-LINQSamples-3fb9811b>. Acesso em 27 de outubro de 2015.

Você também pode gostar