C#: Classes e objetos

1. Por que as classes são necessárias

C# é uma linguagem orientada a objetos na qual quase tudo é um objeto. Anteriormente, escrevemos código usando instruções de nível superior, mas os programas reais em C# são construídos a partir de classes. Uma classe é um modelo para objetos — ela define dados (campos) e comportamento (métodos), enquanto um objeto é uma instância concreta de uma classe.


2. Definição de classe

Use a palavra-chave class para definir uma classe. Os nomes das classes devem seguir a convenção PascalCase (colocar em maiúscula a primeira letra de cada palavra).

CSHARP
class Person
{
    public string Name;
    public int Age;

    public void SayHello()
    {
        System.Console.WriteLine($"Hello, I'm {Name}, {Age} years old.");
    }
}

3. Criação de objetos

Use a palavra-chave new para criar um objeto a partir de uma classe:

CSHARP
Person p = new Person();
p.Name = "Tom";
p.Age = 18;
p.SayHello();
TEXT 📖 Somente leitura
Hello, I'm Tom, 18 years old.

Cada new cria um objeto independente com sua própria cópia dos campos.


4. Campos e inicialização de campos

É possível atribuir valores iniciais aos campos na declaração:

CSHARP
class Student
{
    public string Name = "Unknown";
    public int Score = 0;
}

Se nenhum valor inicial for atribuído, os tipos numéricos assumem por padrão o valor 0, e os tipos de referência assumem por padrão o valor null.

Os modificadores de acesso controlam a visibilidade dos campos:

Modificador Significado
public Acessível de qualquer lugar
private Acessível apenas dentro da classe (padrão)

Normalmente, os campos são definidos como private e o acesso é controlado por meio de métodos ou propriedades.

▶ Exemplo

CSHARP
using System;

class BankAccount
{
    private decimal balance = 1000m;

    public void Deposit(decimal amount)
    {
        balance += amount;
        Console.WriteLine($"Deposited {amount}, balance is {balance}");
    }

    public void ShowBalance()
    {
        Console.WriteLine($"Current balance: {balance}");
    }
}

class Program
{
    static void Main()
    {
        BankAccount acc = new BankAccount();
        acc.ShowBalance();
        acc.Deposit(500m);
    }
}
▶ Experimente
TEXT 📖 Somente leitura
Current balance: 1000
Deposited 500, balance is 1500

5. Métodos

Métodos são funções definidas dentro de uma classe que descrevem o comportamento de um objeto. Os métodos podem acessar campos dentro da mesma classe:

CSHARP
class Calculator
{
    private int result = 0;

    public void Add(int value)
    {
        result += value;
    }

    public int GetResult()
    {
        return result;
    }
}

6. A palavra-chave “this”

this refere-se à instância atual do objeto. Seu uso mais comum é distinguir campos de parâmetros com o mesmo nome:

CSHARP
class Person
{
    public string Name;
    public int Age;

    public Person(string Name, int Age)
    {
        this.Name = Name;
        this.Age = Age;
    }
}

7. Construtores

Os construtores são chamados automaticamente quando um objeto é criado e servem para inicializar o objeto.

(1) Construtor sem parâmetros

Se nenhum construtor for definido, o compilador gera automaticamente um construtor sem parâmetros:

CSHARP
class Dog
{
    public string Name;

    public Dog()
    {
        Name = "Unnamed";
    }
}

(2) Construtor parametrizado

CSHARP
class Dog
{
    public string Name;

    public Dog(string name)
    {
        Name = name;
    }
}

⚠️ Depois que você definir qualquer construtor, o compilador não irá mais gerar automaticamente um construtor sem parâmetros.

(3) Sobrecarga de construtores

É possível definir vários construtores com parâmetros diferentes:

CSHARP
class Dog
{
    public string Name;
    public int Age;

    public Dog()
    {
        Name = "Unnamed";
        Age = 0;
    }

    public Dog(string name)
    {
        Name = name;
        Age = 0;
    }

    public Dog(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

(4) Encadeamento de construtores

Use this(...) para que um construtor chame outro, evitando a duplicação de código:

CSHARP
class Dog
{
    public string Name;
    public int Age;

    public Dog() : this("Unnamed", 0) { }

    public Dog(string name) : this(name, 0) { }

    public Dog(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

▶ Exemplo

CSHARP
using System;

class Book
{
    public string Title;
    public string Author;
    public decimal Price;

    public Book() : this("Unknown", "Unknown", 0m) { }

    public Book(string title, string author) : this(title, author, 29.9m) { }

    public Book(string title, string author, decimal price)
    {
        Title = title;
        Author = author;
        Price = price;
    }

    public void PrintInfo()
    {
        Console.WriteLine($"\"{Title}\" Author: {Author} Price: {Price}");
    }
}

class Program
{
    static void Main()
    {
        Book b1 = new Book();
        Book b2 = new Book("C# Basics", "Alice");
        Book b3 = new Book("Advanced C#", "Bob", 59.9m);

        b1.PrintInfo();
        b2.PrintInfo();
        b3.PrintInfo();
    }
}
▶ Experimente
TEXT 📖 Somente leitura
"Unknown" Author: Unknown Price: 0
"C# Basics" Author: Alice Price: 29.9
"Advanced C#" Author: Bob Price: 59.9

8. Destruidores

Um destrutor é chamado antes de um objeto ser recolhido pelo coletor de lixo. A sintaxe é ~ClassName():

CSHARP
class Resource
{
    ~Resource()
    {
        Console.WriteLine("Object is being reclaimed");
    }
}

📌 O C# possui coleta automática de lixo (GC), portanto, raramente é necessário escrever um destrutor manualmente. Os destrutores são usados apenas para liberar recursos não gerenciados (como identificadores de arquivos e conexões com bancos de dados), o que será discutido em detalhes em lições posteriores.


9. Inicializadores de objetos

O C# 3.0 introduziu a sintaxe de inicialização de objetos, que permite atribuir valores diretamente a campos ou propriedades públicas ao usar new:

CSHARP
Person p = new Person { Name = "Lily", Age = 20 };

Isso equivale a:

CSHARP
Person p = new Person();
p.Name = "Lily";
p.Age = 20;

Os inicializadores de objetos podem ser combinados com construtores parametrizados:

CSHARP
Person p = new Person("Lily") { Age = 20 };

▶ Exemplo

CSHARP
using System;

class Rectangle
{
    public double Width = 1;
    public double Height = 1;

    public double Area()
    {
        return Width * Height;
    }
}

class Program
{
    static void Main()
    {
        Rectangle r1 = new Rectangle();
        Rectangle r2 = new Rectangle { Width = 5, Height = 3 };
        Rectangle r3 = new Rectangle { Width = 10 };

        Console.WriteLine($"r1 area: {r1.Area()}");
        Console.WriteLine($"r2 area: {r2.Area()}");
        Console.WriteLine($"r3 area: {r3.Area()}");
    }
}
▶ Experimente
TEXT 📖 Somente leitura
r1 area: 1
r2 area: 15
r3 area: 10

10. Diferença entre “new” e “null”

Conceito Significado
new ClassName() Cria um objeto na pilha e retorna uma referência a esse objeto
null Não aponta para nenhum objeto; é o valor padrão para tipos de referência
CSHARP
Person p1 = new Person();
Person p2 = null;

Console.WriteLine(p1 == null);
Console.WriteLine(p2 == null);
TEXT 📖 Somente leitura
False
True

⚠️ Acessar um membro em uma referência null gera um NullReferenceException, o erro de tempo de execução mais comum em C#:

CSHARP
Person p = null;
p.SayHello();

💡 Verifique se há null antes de acessar:

CSHARP
if (p != null)
{
    p.SayHello();
}

❓ Perguntas Frequentes

P: O que acontece se eu não definir um construtor? R: O compilador gera automaticamente um construtor sem parâmetros que atribui valores padrão aos campos.

P: Ainda é possível criar um objeto sem parâmetros depois de definir um construtor parametrizado? R: Não, a menos que você defina manualmente um construtor sem parâmetros também.

P: Isso pode ser usado em métodos estáticos? R: Não, isso se refere à instância atual, e os métodos estáticos não estão associados a uma instância.

P: Os inicializadores de objetos podem atribuir valores a campos privados? R: Não, eles só podem inicializar membros acessíveis (campos ou propriedades públicos).

P: “null” e 0 são a mesma coisa? R: Não. “null” significa “sem referência”, enquanto 0 é um valor de tipos numéricos. Tipos de valor não podem ser “null”.

📖 Resumo

📝 Exercícios

  1. Defina uma classe Car com os campos Brand (string) e Speed (int), um método Accelerate(int amount) que aumenta Speed e um construtor sem parâmetros que inicializa Speed como 0
  2. Adicione um construtor parametrizado Car(string brand) à classe Car e use this(...) para implementar o encadeamento de construtores
  3. Use um inicializador de objeto para criar um objeto Car e definir Brand e Speed; em seguida, chame o método Accelerate e exiba o valor final de Speed
  4. Escreva um código que demonstre o seguinte: crie uma referência Car atribuída a null, tente acessar seu membro, use try-catch para capturar o NullReferenceException e imprima uma mensagem
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%