Back-End

20 jul, 2018

Iniciando com C# – Parte 03: Orientação a Objetos

Publicidade

Já vimos um pouquinho do C#, como ele funciona, seus tipos de dados e estruturas úteis. Agora, entraremos num tópico bem importante e abrangente: Orientação a Objetos.

Em nossos programas, realizaremos a implementação de objetos existentes no mundo real. Vamos pegar como exemplo uma conta bancária.

Uma conta bancária possui algumas informações dentro dela, como o número, o nome do titular, o saldo e a data de abertura.

Podemos guardar esses valores em variáveis, como podemos ver a seguir:

Mas um banco não possui apenas a Maria como cliente. E se tivermos que fazer para mais pessoas? Temos que criar novas variáveis e formas de diferenciá-las, começando a ficar complexo.

Para organizarmos isso de forma que não nos confundamos no futuro e consigamos validar os dados de modo a não esquecer de validar alguma variável  – que poderia acontecer, devido a imensa quantidade de variáveis que seriam criadas  – vamos caracterizar a Conta como uma Classe –  representação de algo do mundo real.

A conta, no entanto, possui algumas características: número, nome do titular, saldo e data de abertura. Essas serão as propriedades da Conta.

Utilizei no exemplo acima modificadores de acesso. Mas o que é isso? Eles são importantes para dizer o que conseguimos acessar de fora daquela classe! No caso, as propriedades que estiverem com o modificador public na frente poderão ser alteradas por membros de fora da classe Conta. Vamos ver daqui a pouco sobre eles, mas guardem que a propriedade Saldo está privada!

Até agora, apenas criamos a representação da nossa Conta. No entanto, ela não existe na memória ainda. Quando ela existir, será criado um objeto dela. Com o objeto, podemos fazer operações e ações.

Para criarmos o objeto, iremos instanciá-lo com o uso da palavra new.

Agora temos um objeto da Conta!

E se quisermos modificar as propriedades da nossa primeiraConta? Podemos fazer de duas formas:

Depois da instanciação:

Durante a instanciação (usando chaves):

Vocês repararam que a propriedade Saldo está sublinhada de vermelho? Se tentarmos compilar nossa solução, ela não funcionará. Lembram do por quê? O modificador de acesso dela é private, então eu não consigo acessar como as outras! É só mudar o modificador para public que o sublinhado sai!

Dessa forma, as características da nossa primeiraConta não ficam espalhadas, como no início do artigo. Elas ficam em conjunto, dentro de um único objeto da memória.

Com o nosso objeto criado, podemos fazer ações com ele. O que podemos fazer com uma conta? Sacar, verificar o saldo, depositar e transferir. Vamos usar os métodos!

Vamos criar o método para efetuar o saque na classe Conta:

Esse método possui o modificador public e poderá ser acessado por outras classes. Após a palavra public, há também a palavra double. Ao adicionarmos isso na assinatura de nosso método, significa que ele retornará um valor do tipo double para nós – o saldo! – sim, os métodos podem retornar algo para a gente! (no caso, o nome do método (“Saca”) está sublinhado em vermelho porque não escrevemos o retorno do método ainda.

Vamos adicionar informações neste método?

Aqui adicionei dois parâmetros: valor e saldo. Quando vamos adicionar um parâmetro em algum método, colocamos primeiro o tipo dele (double) e depois o nome desejado.

No corpo do método, coloquei uma estrutura condicional para verificar se o saldo é maior que o valor. Afinal, não posso sacar um valor que não possui na minha conta. Caso a condição seja verdadeira, é decrementado o valor de saldo.

Observação: utilizar saldo -= valor é a mesma coisa que saldo = saldo-valor!

Um método foi criado. Bacana! Mas ele não está sendo chamado em lugar nenhum! Como podemos fazer para utilizá-lo?

Sabemos que ele foi adicionado na classe Conta, então fazemos o seguinte:

Como ele pertence à classe Conta, ele está presente no nosso objeto primeiraConta. Chamamos ele passando dentro do parênteses os valores dos parâmetros respectivamente separados por vírgula. Notem que o segundo parâmetro é primeiraConta.Saldo. Isso quer dizer que estou passando a propriedade de saldo do meu objeto como parâmetro.

Vamos ver como fica executando no console?

Certinho! O saldo anterior de Maria era 2500, conforme colocamos na construção do objeto. Removendo 500, que foi o parâmetro que passamos, fica 2000 na conta!

Dentro da orientação a objetos, há também as Interfaces. Elas são como “contratos” das nossas classes, utilizadas quando queremos que um comportamento seja “forçado” em alguma classe.

Por exemplo, vamos criar a interface IImpostos –  por convenção, a nomenclatura de interfaces começa com “I”.

A criação de uma interface é bem parecida com a de uma classe. Trocamos o “class” por “interface”.

No entanto, este nosso “contrato” tem algumas particularidades. A declaração de métodos é feita sem os modificadores de acesso (sempre serão públicos), e os métodos não possuem corpo.

Agora, vamos utilizar uma interface na nossa Conta!

Para fazermos o uso de uma interface, utilizamos “: + nome da interface” após o nome da classe.

Como podemos ver, a palavra IImpostos está sublinhada em vermelho. Isso acontece porque não estamos seguindo o contrato que assinamos! Havíamos colocado na interface um método que calcula os impostos, mas não estamos implementando-o na classe Conta; algo que é obrigatório!

Clicando na lâmpada, há uma opção “Implement Interface”. Cliquemos nessa, e o método da interface aparecerá agora na nossa classe, esperando nossa implementação!

Quando criado, é colocado como corpo de forma automática o “throw new NotImplementedException();”. Isso significa que quando esse método for executado, uma exceção será exibida ao usuário, alegando que não foi efetuada nenhuma implementação ou ação a ser realizada.

Tipo Valor x Tipo Referência

Tipo Valor: são armazenados no próprio dado, sendo acessados diretamente. São eles: tipos numéricos, booleanos, char, Date, estruturas e enumerações.

Tipos Referência: dados armazenados na memória Heap (objetos dinâmicos). Aponta para lugares na memória, sendo acessados indiretamente. São eles: String, arrays, classes e delegates.

Ao fazer a alteração do valor de um tipo valor, alteramos de fato o valor dele na memória, pois cada um possui seu próprio espaço.

No entanto, trabalhar com tipo referência é um pouco diferente. Não alteramos o valor daquela propriedade em si. Ao atribuir um objeto a outro, estamos, na verdade, falando que as duas variáveis irão apontar para o mesmo espaço da memória. Ou seja, alterando uma, todas serão alteradas – por isso o comportamento diferenciado.

Continuamos o assunto na próxima parte!

Referências