4 princípios básicos da orientação à objetos com C#
A orientação à objetos muitas vezes quando explicada para os novatos na programação, parece ser um bicho de sete cabeças, algo sobrenatural, neste artigo procurarei explicar com exemplos simples o que são e como utilizá-las de forma adequada, já que é algo básico para qualquer um que almeja trabalhar na área da programação e precisa passar por um processo de entrevista com o mínimo de conhecimento destes pilares.
Este material foi um compilado de uma aula que ministrei e que resolvi compartilhar uma vez que há muita confusão nestes princípios.
Herança
A herança é uma parte essencial da programação orientada à objetos, é onde um objeto pode herdar as propriedades de outro, costumamos até falar que um objeto é filho do outro.
Teremos sempre uma classe “Base “ da qual as outras herdarão suas características.
Podemos comparar com o exemplo acima, o que será demonstrado no código abaixo.
Neste caso, poderá ver que “Cachorro” é um objeto “filho” de “Animal”, pois podemos ter outras classes que serão herdados de “Animal”, como criado ali “Gato” e “Peixe”.
Podemos estabelecer nesta classe “pai” todas as propriedades e métodos que serão comuns aos filhos, sendo assim vemos que peixe possui a propriedade respirar diferente dos outros animais.
Já Cor e Idade, como são comuns, só são definidas no objeto pai.
public class Animal
{
public string Cor { get; set; }
public int Idade { get; set; }
public virtual void FazerBarulho()
{
Console.WriteLine("barulho genérico de um animal qualquer");
}
public virtual void Comer()
{
Console.WriteLine("Comer");
}
public virtual void Respirar()
{
Console.WriteLine("Respirar ar");
}
}
public class Gato : Animal
{
public override void FazerBarulho()
{
Console.WriteLine("O Gato mia");
}
}
Em se tratando de software, teremos coisas do mundo real sendo levadas para a sua aplicação, portanto teremos por exemplo, um funcionário, um cliente, um fornecedor, todos podem herdar características de uma classe “Pessoa” e assim formarem sub-classes de uma classe “pai”.
Seguindo esta idéia, ao instanciar uma classe do tipo “Gato” vemos que mesmo sem que ela possua propriedades “Cor”, “Idade”, “Respirar” elas estão disponíveis para usar, por que foram herdadas da classe pai.
Encapsulamento
Este princípio da Orientação à Objetos define a visibilidade e acesso de propriedades, métodos e classes, podendo deixar ocultas através de modificadores de acesso quando não é necessário expor algumas propriedades e métodos.
- public: sem restrições no acesso
- internal: restrito ao assembly onde está contido
- protected: restrito a class que o contém e a quaisquer classes derivadas
- protected internal: lógica OU para o internal e protected.
- private: restrito a classe que o contém
Vejam que o método “MostrarUnhas” é privado, então dentro da própria classe conseguimos utilizar, mas fora dela, não é visível !
Abstração
Devemos criar classes definidas como abstratas, que servirão de “formato” para outras classes, em que cada classe derivada desta classe abstrata terá obrigatoriamente as propriedades que esta definir.
Uma classe abstrata
- não será completamente implementada
- deve ter o modificador “abstract”
- métodos não implementados(abstratos) recebem o modificador “abstract”.
- não podem ser instanciadas diretamente
Já quando criarmos uma classe a partir da classe abstrata, estas classes deverão ter o “override” nos métodos que iremos sobrescrever.
Para mais exemplos, acessem este post que fiz há um bom tempo:
Classes Abstratas x Interfaces (exemplos com C#) | by Marcio Nizzola | Medium
Polimorfismo
O Polimorfismo, quer dizer “que pode assumir muitas formas”, é o conceito que permite que possamos fazer com que uma classe possa ser tratada de forma homogênea, baseada na classe da qual ela é derivada.
Utilizando o exemplo acima, onde tínhamos as classes “Cachorro” e “Gato” que são herdadas do tipo “Animal”, nós podemos nos referir à classes derivadas mencionando o tipo “pai”, inclusive compor uma lista baseada no tipo “pai”.
Animal[] animals = new Animal[4];
animals[0] = new Animal();
animals[1] = new Cachorro();
animals[2] = new Gato();
animals[3] = new Peixe();
foreach (Animal animal in animals)
{
animal.FazerBarulho();
animal.Comer();
}
Observe que criamos um array de “Animal” e dentro dele criamos elementos dos tipos Animal, Cachorro, Gato, Peixe, mesmo sendo a lista do tipo “Animal” isto é o conceito sendo aplicado na prática. Pois as classes “Cachorro” e “Gato” são “filhas” da classe “Animal”. Outro detalhe é que o método “FazerBarulho” foi sobrescrito (override) nas classes filhas, sendo assim quando executado no laço, o que vai executar é o código das classes filhas.
public class Animal
{
public virtual void FazerBarulho()
{
Console.WriteLine("barulho genérico de um animal qualquer");
}
public virtual void Comer()
{
Console.WriteLine("Comer");
}
public virtual void Respirar()
{
Console.WriteLine("Respirar ar");
}
}
public class Cachorro : Animal
{
public override void FazerBarulho()
{
Console.WriteLine("O cachorro late");
}
}
public class Gato : Animal
{
public override void FazerBarulho()
{
Console.WriteLine("O Gato mia");
}
}
public class Peixe : Animal
{
public override void Respirar()
{
Console.WriteLine("O peixe respira pela água");
}
}
Gostou do artigo? clique no ícone👏e me siga para ver as próximas publicações !!
Referências
What Are the 4 Fundamental Characteristics in C# OOP? | by Stanislava Stoeva | Medium