Partilhar via


Classes C#

Sugestão

Novo no desenvolvimento de software? Começa primeiro pelos tutoriais para começar . Vais encontrar classes assim que precisares de modelar objetos com comportamento e estado.

Experiente noutra língua? As classes C# são semelhantes às classes em Java ou C++. Folheie a secção de inicializadores de objetos para padrões específicos de C# e consulte Registos para uma alternativa focada em dados.

Uma classe é um tipo de referência que define um blueprint para objetos. Quando cria uma variável de um tipo de classe, a variável mantém uma referência a um objeto no heap gerido. A variável não guarda os dados do objeto em si. Atribuir uma variável de classe a outra variável copia a referência, de modo que ambas apontam para o mesmo objeto. As classes são a forma mais comum de definir tipos personalizados em C#. Usa-os quando precisares de comportamentos complexos, herança ou identidade partilhada entre referências.

Quando usar classes

Use uma classe quando:

  • O tipo possui um comportamento complexo ou lida com um estado mutável.
  • Precisas de herança para criar uma classe base com especializações derivadas, ou para criar um tipo derivado que estenda uma classe existente.
  • As instâncias representam uma identidade partilhada, não objetos que por acaso têm valores iguais. Duas referências ao mesmo objeto devem manter-se sincronizadas.
  • O tipo é grande ou de longa duração e beneficia da alocação de heap e da semântica de referência.

Declarar uma classe

Defina uma classe com a class palavra-chave seguida do nome do tipo. Um modificador de acesso opcional controla a visibilidade. A predefinição é internal. Especifique public para permitir que chamadores de outras assemblies usem os seus tipos.

public class Customer
{
    public string Name { get; set; }

    public Customer(string name) => Name = name;
}

O corpo da classe contém campos, propriedades, métodos e eventos, coletivamente chamados de membros da classe. O nome deve ser um identificador C# válido.

Criar objetos

Uma classe define um tipo, mas não é um objeto em si. Crias um objeto (uma instância da classe) com a new palavra-chave:

var customer = new Customer("Allison");
Console.WriteLine(customer.Name); // Allison

A variável customer tem uma referência ao objeto, não ao objeto em si. Podes atribuir múltiplas variáveis ao mesmo objeto. As alterações através de uma referência são visíveis através da outra:

var c1 = new Customer("Grace");
var c2 = c1; // both variables reference the same object

c2.Name = "Hopper";
Console.WriteLine(c1.Name); // Hopper — c1 sees the change made through c2

Este comportamento de partilha de referências é uma das distinções entre classes e estruturas. Com structs, a atribuição copia os dados. Mais importante ainda, as classes apoiam a herança. Podes construir hierarquias onde tipos derivados reutilizam e especializam comportamentos a partir de uma classe base. Os structs não podem participar em hierarquias de herança. Para mais informações sobre a distinção, veja Tipos de valor e tipos de referência.

Construtores e inicialização

Quando crias uma instância, queres que os seus campos e propriedades sejam inicializados com valores úteis. C# oferece várias abordagens: inicializadores de campos, parâmetros de construtores, construtores primários e propriedades obrigatórias.

Os inicializadores de campo definem um valor padrão diretamente na declaração do campo:

public class Container
{
    private int _capacity = 10;
}

Os inicializadores de campos atribuem um valor padrão razoável a um campo ou propriedade. Isto distingue-o das abordagens seguintes, onde os utilizadores podem fornecer o valor inicial.

Os parâmetros do construtor exigem que os invocadores forneçam valores:

public class Container
{
    private int _capacity;

    public Container(int capacity) => _capacity = capacity;
}

Os construtores primários (C# 12+) adicionam parâmetros diretamente à declaração da classe. Esses parâmetros estão disponíveis em todo o corpo da turma:

public class Container(int capacity)
{
    private int _capacity = capacity;
}

Construtores primários e inicializadores de campos podem trabalhar em conjunto: o inicializador _capacity = capacity de campos usa o parâmetro construtor primário como seu valor. Este padrão permite-lhe capturar argumentos de construtores em campos com uma única declaração concisa.

As propriedades obrigatórias obrigam os chamadores a definir propriedades específicas através de um inicializador de objetos:

public class Person
{
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
}
// var missing = new Person(); // Error: required properties not set
var person = new Person { FirstName = "Grace", LastName = "Hopper" };
Console.WriteLine($"{person.FirstName} {person.LastName}"); // Grace Hopper

Para uma análise mais aprofundada dos padrões de construtores, incluindo validação de parâmetros e encadeamento de construtores, consulte Construtores.

Classes estáticas

Uma static classe não pode ser instanciada e contém apenas membros estáticos. Use classes estáticas para organizar métodos utilitários que não operam em dados de instância:

static class MathHelpers
{
    public static double CircleCircumference(double radius) =>
        2 * Math.PI * radius;
}
double circumference = MathHelpers.CircleCircumference(5.0);
Console.WriteLine($"Circumference: {circumference:F2}"); // Circumference: 31.42

A biblioteca de classes .NET inclui muitas classes estáticas, como Math e Console. Uma classe estática está implicitamente selada. Não se pode derivar dela nem instanciar.

Inicializadores de objeto

Os inicializadores de objetos permitem-lhe definir propriedades ao criar um objeto, sem escrever um construtor para cada combinação de valores:

class ConnectionOptions
{
    public string Host { get; init; } = "localhost";
    public int Port { get; init; } = 80;
    public bool UseSsl { get; init; }
}
var options = new ConnectionOptions
{
    Host = "db.example.com",
    Port = 5432,
    UseSsl = true
};
Console.WriteLine($"{options.Host}:{options.Port} (SSL: {options.UseSsl})");
// db.example.com:5432 (SSL: True)

Os inicializadores de objetos funcionam com qualquer propriedade acessível que tenha um set ou init acessor. Combinam-se naturalmente com as propriedades required e com construtores que aceitam alguns parâmetros, permitindo que o chamador defina outros.

Quando a propriedade é uma coleção, pode usar expressões de Coleção (referência C#) para inicializar esse objeto.

Herança

As classes apoiam a herança. Pode definir uma nova classe que reutilize, estenda ou modifique o comportamento de uma classe existente. A classe de onde herdas é a classe base, e a nova classe é a classe derivada:

var manager = new Manager("Satya", "Engineering");
Console.WriteLine($"{manager.Name} manages {manager.Department}");
// Satya manages Engineering

Uma classe pode herdar de uma classe base e implementar múltiplas interfaces. As classes derivadas herdam todos os membros da classe base, exceto os construtores. Para mais informações, consulte Herança e Interfaces.

Consulte também