Programação procedural e programação orientada a objetos
Antes do surgimento das classes, linguagens como C não possuíam esse conceito. O estilo de programação sem classes e objetos, característico da linguagem C, é chamado de programação procedural.
Programação procedural: um programa é uma sequência de instruções, e o foco principal é otimizar os passos de execução.
Com a existência das classes, podemos implementar a programação orientada a objetos.
Programação orientada a objetos: o programa é composto por um conjunto de classes encapsuladas. A ideia central é agrupar os dados e as funções que manipulam esses dados em unidades logicamente relacionadas; essas unidades são denominadas classes (class).
Definição de classe
Uma classe é uma estrutura de dados que contém dados armazenados e código executável. Ela possui dois grupos de membros:
- Membros de dados (Data Members): armazenam os atributos do objeto: campos (Fields), constantes (Constants)
- Membros de função (Function Members): implementam a lógica de comportamento dos objetos: métodos, propriedades, construtores, destrutores, operadores, indexadores, eventos
A classe é um conjunto que encapsula dados e funções com relação lógica, utilizado para modelar entidades do mundo real ou abstrato.
Resumindo, uma classe é uma estrutura de dados formada por dados e funções. Podemos criar objetos a partir de uma classe; acessamos os dados e membros por meio dos objetos, e também diretamente de dentro da própria classe.
Declaração de classe
A palavra-chave class define apenas um modelo de classe, ela não cria instâncias de objetos. Um modelo é composto por três partes: nome da classe, membros da classe e características da classe.
Sintaxe
class NomeClasse
{
// declaração de membros (campos, métodos, a ordem não é obrigatória)
}Code language: JavaScript (javascript)
A declaração de classe também é conhecida como definição de classe (class definition)
class Program
{
static void Main(string[] args)
{
AddCalculator addCalculator = new AddCalculator();
SubCalculator subCalculator = new SubCalculator();
}
}
class AddCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Add()
{
return A + B;
}
}
class SubCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Subtract()
{
return A - B;
}
}Code language: JavaScript (javascript)
No exemplo acima, duas classes são declaradas: uma para operações de soma e outra para subtração. Dentro da função Main do programa principal, criamos instâncias dessas duas classes para utilizá-las.
Conteúdo proveniente do site foxdevelop.com
Não é obrigatório declarar as classes de cima para baixo. Você pode declarar classes na parte inferior do código e chamá-las na função Main que está acima. A classe é apenas um modelo, um projeto. O código não é executado sequencialmente de cima para baixo; a execução começa em Main, e o programa busca o modelo correspondente quando necessitar da classe.

Membros da classe
Campos (Fields)
Um campo é uma variável pertencente a uma classe. Pode ser um tipo nativo ou definido pelo usuário e suporta leitura e gravação de dados.
Tipo NomeCampo;
class MyClass
{
int MyField; // campo do tipo int chamado MyField
}Code language: JavaScript (javascript)
Diferença importante em relação ao C/C++: o C# não possui variáveis globais. Todos os campos devem ser declarados dentro de um tipo (classe ou estrutura).
Regras de inicialização de campos
(1) Inicialização implícita (sem atribuição de valor)
O compilador atribui automaticamente um valor padrão correspondente ao tipo; cada tipo possui um valor padrão diferente.
int F1; // valor padrão 0
string F2; // valor padrão nullCode language: JavaScript (javascript)
A tabela abaixo lista os tipos C# e seus valores padrão para campos. Essa regra vale apenas para campos; variáveis locais devem ser inicializadas manualmente pelo desenvolvedor.
Tipos de valor primitivos
| Tipo de dado | Valor padrão | Descrição |
|---|---|---|
sbyte | 0 | Inteiro de 8 bits com sinal |
byte | 0 | Inteiro de 8 bits sem sinal |
short | 0 | Inteiro de 16 bits com sinal |
ushort | 0 | Inteiro de 16 bits sem sinal |
int | 0 | Inteiro de 32 bits com sinal |
uint | 0 | Inteiro de 32 bits sem sinal |
long | 0L | Inteiro de 64 bits com sinal |
ulong | 0UL | Inteiro de 64 bits sem sinal |
float | 0.0f | Ponto flutuante de precisão simples |
double | 0.0d | Ponto flutuante de precisão dupla |
decimal | 0.0m | Decimal de alta precisão |
char | '\0' (caractere nulo, ASCII 0) | Caractere único |
bool | false | Tipo booleano |
Enumeração Enum | Elemento da enumeração correspondente ao inteiro base 0 | Enumerações são baseadas em inteiros, valor padrão é 0 |
Estrutura struct | Cada campo recebe seu próprio valor padrão | Tipo de valor personalizado, todo zerado |
Tipos de referência
Todos os tipos de referência têm valor padrão igual a null, isso significa que a variável não aponta para nenhum objeto na memória heap.
Ou seja, nenhum endereço de memória válido é armazenado. Lembre do diagrama de memória visto anteriormente: tipos de referência guardam endereços da heap como 000001 01010. Quando é null, nenhum endereço válido está salvo.
| Categoria de tipo | Exemplos de tipos | Valor padrão |
|---|---|---|
| Tipos de referência nativos | string, object | null |
Classe personalizada class | Person Student | null |
| Vetores (todas as dimensões) | int[], string[,] | null |
| Delegados / Eventos | Action, Func, delegate personalizado | null |
Interface interface | Toda variável de interface | null |
Exemplos
string str; // padrão null
Student jason; // classe personalizada, padrão null
int[] arr; // vetor, padrão null
Action callback; // delegado, padrão nullCode language: JavaScript (javascript)
Tipos anuláveis (Nullable / T?)
Se adicionarmos um ponto de interrogação ? após um tipo de valor básico, criamos um novo tipo que aceita a ausência de valor. Por exemplo: int age; recebe 0 por padrão se não receber atribuição. Se quisermos representar que não há valor algum, escrevemos int? age2;. age2 é um tipo anulável e aceita receber null: int? age2 = null;
Um tipo anulável é um ValueType encapsulado, seu valor padrão é null, significando “sem valor válido”.
| Sintaxe de declaração | Valor padrão |
|---|---|
int? num | null |
bool? flag | null |
decimal? price | null |
class Test
{
int a; // automaticamente 0
string b; // automaticamente null
bool c; // automaticamente false
}Code language: JavaScript (javascript)
(2) Inicialização explícita
Atribua um valor usando = no momento da declaração. O valor atribuído deve ser conhecido em tempo de compilação; não é permitido usar valores aleatórios ou dados de entrada do usuário diretamente.
int days = 25;
string word = "foxdevelop";Code language: JavaScript (javascript)
(3) Forma abreviada para vários campos do mesmo tipo
Várias variáveis do mesmo tipo podem ser declaradas juntas separadas por vírgula. É proibido misturar tipos diferentes numa mesma linha de declaração
int player, blood = 25;
string title, subTitle = "hi welcome to foxdevelop.com";Code language: JavaScript (javascript)
Métodos (Methods)
Definição de método
Um método é um bloco de código nomeado, reutilizável e executável, equivalente às funções membro do C++. Ao ser invocado, executa o código interno e retorna o controle para o ponto de chamada. Dividem-se em métodos com retorno e métodos sem retorno.
Quatro elementos de um método
- Tipo de retorno: use
voidquando não houver valor retornado - Nome do método
- Lista de parâmetros: os parênteses
()são obrigatórios mesmo sem parâmetros - Corpo do método: código executável delimitado por
{}
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
robot.SayHello();
}
}
class Robot
{
public void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
A palavra reservada public antes de public void SayHello() é um modificador de acesso, permite chamar essa função de fora da classe com a sintaxe nomeObjeto.NomeMetodo. Sem o modificador public, o acesso padrão é private. Métodos privados só podem ser chamados dentro da classe; não são acessíveis de fora, mesmo por meio de uma instância como robot.

Criação de variáveis de classe e instâncias
1. Características básicas dos tipos de referência
As classes pertencem aos tipos de referência. A memória é dividida em duas áreas:
- Pilha (Stack): armazena variáveis de referência (ponteiros para endereços de memória)
- Heap: armazena os dados reais dos objetos
2. Criação de objeto passo a passo
1 Apenas declaração da variável de referência (somente memória alocada na pilha, sem objeto no heap)
Robot robot;
// Apenas espaço para referência reservado na pilha, valor indefinido, não existe objeto no heap
Code language: JavaScript (javascript)

2 Alocação de memória no heap com o operador new
new NomeTipo();Code language: JavaScript (javascript)
- Aloca memória no heap e inicializa automaticamente todos os campos com seus valores padrão
- Retorna o endereço de referência do objeto no heap e atribui à variável da pilha
robot = new Robot();
Code language: JavaScript (javascript)

class Program
{
static void Main(string[] args)
{
Robot robot;
robot = new Robot();
}
}
class Robot
{
void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
3. Declaração e instanciação numa única linha
Robot robot = new Robot();Code language: JavaScript (javascript)
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
}
}Code language: JavaScript (javascript)
Definição de classe