Conceitos Essenciais da Orientação a Objetos
Uma classe funciona como um modelo para a criação de objetos. Ela é uma abstração que descreve as características e comportamentos de objetos concretos. Quando um aplicativo .NET é iniciado, o assembly é carregado pelo CLR (Common Language Runtime). Ao encontrar uma classe pela primeira vez, o runtime carrega seus membros estáticos, otimizando o uso de recursos.
Um objeto é uma instância concreta criada a partir de uma classe.
- Campo: Representa o estado de um objeto.
- Método: Define uma ação que o objeto pode executar.
- Herança: Permite que uma classe (subclasse) herde membros de outra classe (superclasse).
Pilares da Orientação a Objetos
Encapsulamento
Princípio que visa ocultar os detalhes de implementação interna, promovendo modularidade e facilitando a manutenção do código.
Herança e Polimorfismo
Uma classe pode herdar de outra para reutilizar código. O polimorfismo permite que uma referência do tipo da superclasse aponte para objetos de subclasses diferentes. O comportamento executado depende do tipo real do objeto em tempo de execução.
Exemplos de polimorfismo em ação:
Superclasse referencia = new Subclasse();
referencia.Metodo(); // Pode chamar a versão da subclasse se houver override
Técnicas comuns incluem o uso de fábricas que retornam a superclasse e a passagem de subclasses como parâmetros de métodos que esperam a superclasse.
Classes Abstratas
Uma classe abstrata serve como base para outras classes. Ela pode conter implementação concreta e membros abstratos (sem implementação) que as subclasses concretas devem implementar. Classes abstratas não podem ser instanciadas diretamente.
public abstract class Forma
{
public abstract double CalcularArea();
}
Interfaces
Uma interface define um contrato de comportamento (métodos, propriedades, eventos) que uma classe ou struct deve implementar. Diferente de uma classe abstrata, uma interface não contém implementação.
public interface IArmazenavel
{
void Salvar();
}
Uma classe pode implementar múltiplas interfaces, mas só pode herdar de uma única classe.
Membros e Modificadores de Acesso
Os membros de uma classe (campos, métodos, propriedades) possuem níveis de acesso que controalm sua visibilidade:
public: Acessível de qualquer lugar.private: Acessível apenas dentro da própria classe.protected: Acessível dentro da classe e de suas subclasses.internal: Acessível dentro do mesmo assembly.
As propriedades são usadas para proteger o acesso aos campos, geralmente através dos acessadores get e set.
Construtores e Destrutores
O construtor é um método especial chamado quando um objeto é criado com a palavra-chave new. Ele inicializa o estado do objeto. Se não for definido, o compilador gera um construtor padrão sem parâmetros.
Classes também podem ter construtores estáticos, executados uma única vez antes do primeiro uso de qualquer membro estático.
public class Produto
{
public string Nome;
public Produto(string nome) // Construtor de instância
{
Nome = nome;
}
}
Tipos de Dados e Referências
Em C#, os tipos de valor (struct, tipos primitiovs como int, bool) são armazenados diretamente na pilha ou como parte de um objeto no heap. Os tipos de referência (classes) armazenam apenas uma referência (endereço de memória) no local de declaração, enquanto o objeto real reside no heap.
Estruturas vs Classes
Structs são tipos de valor usados para representar dados leves. Elas não suportam herança (exceto de interfaces) e são ideais para pequenas estruturas de dados que possuem comportamento limitado.
public struct Ponto2D
{
public double X;
public double Y;
}
Classes são tipos de referência usados para modelar objetos mais complexos, que requerem encapsulamento, herança e polimorfismo.
Coleções e Genéricos
As coleções genéricas (ex: List<T>, Dictionary<TKey, TValue>) fornecem type safety e desempenho superior às coleções não genéricas (ex: ArrayList, Hashtable) que dependem do tipo base object.
List<string> nomes = new List<string>();
nomes.Add("Ana");
nomes.Add("Carlos");
Delegados e Eventos
Um delegado é um tipo que referencia métodos com uma assinatura específica. Ele permite tratar métodos como variáveis, passando-os como parâmetros.
public delegate void LogHandler(string mensagem);
public class Logger
{
public void EscreverNoConsole(string msg) => Console.WriteLine(msg);
}
// Uso
Logger logger = new Logger();
LogHandler handler = logger.EscreverNoConsole;
handler("Iniciando aplicação");
Um evento é um encapsulamento de um delegado, fornecendo uma maneira segura de publicar e assinar notificações. Apenas a classe que declara o evento pode invocá-lo.
Tratamento de Exceções
O bloco try-catch é usado para capturar e tratar erros em tempo de execução.
try
{
var resultado = 10 / divisor;
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Erro: {ex.Message}");
}
finally
{
// Código executado sempre, ocorrendo exceção ou não
}
Serialização
É o processo de converter um objeto em um formato que pode ser armazenado ou transmitido (como XML ou JSON) e reconstruído posteriormente. É útil para persistência de dados ou comunicação entre sistemas.