Introdução às aulas
Tipos de referência
Um tipo que é definido como um class
é um tipo de referência. Em tempo de execução, quando você declara uma variável de um tipo de referência, a variável contém o valor null
até que você crie explicitamente uma instância da classe usando o new
operador ou atribua-lhe um objeto de um tipo compatível criado em outro lugar, conforme mostrado no exemplo a seguir:
//Declaring an object of type MyClass.
MyClass mc = new MyClass();
//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;
Quando o objeto é criado, memória suficiente é alocada no heap gerenciado para esse objeto específico, e a variável mantém apenas uma referência ao local desse objeto. A memória usada por um objeto é recuperada pela funcionalidade de gerenciamento automático de memória do CLR, que é conhecida como coleta de lixo. Para obter mais informações sobre a coleta de lixo, consulte Gerenciamento automático de memória e coleta de lixo.
Declarar classes
As classes são declaradas usando a class
palavra-chave seguida por um identificador exclusivo, conforme mostrado no exemplo a seguir:
//[access modifier] - [class] - [identifier]
public class Customer
{
// Fields, properties, methods and events go here...
}
Um modificador de acesso opcional precede a class
palavra-chave. O acesso padrão para um class
tipo é internal
. Como public
é usado nesse caso, qualquer pessoa pode criar instâncias dessa classe. O nome da classe segue a class
palavra-chave. O nome da classe deve ser um nome de identificador C# válido. O restante da definição é o corpo da classe, onde o comportamento e os dados são definidos. Campos, propriedades, métodos e eventos em uma classe são coletivamente chamados de membros da classe.
Criação de objetos
Embora às vezes sejam usados de forma intercambiável, uma classe e um objeto são coisas diferentes. Uma classe define um tipo de objeto, mas não é um objeto em si. Um objeto é uma entidade concreta baseada em uma classe, e às vezes é referido como uma instância de uma classe.
Os objetos podem ser criados usando a new
palavra-chave seguida pelo nome da classe, da seguinte forma:
Customer object1 = new Customer();
Quando uma instância de uma classe é criada, uma referência ao objeto é passada de volta para o programador. No exemplo anterior, object1
é uma referência a um objeto baseado em Customer
. Esta referência refere-se ao novo objeto, mas não contém os dados do objeto em si. Na verdade, você pode criar uma referência de objeto sem criar um objeto:
Customer object2;
Não recomendamos a criação de referências de objeto que não se refiram a um objeto porque a tentativa de acessar um objeto por meio dessa referência falha em tempo de execução. Uma referência pode referir-se a um objeto, criando um novo objeto ou atribuindo-lhe um objeto existente, como este:
Customer object3 = new Customer();
Customer object4 = object3;
Esse código cria duas referências de objeto que se referem ao mesmo objeto. Portanto, quaisquer alterações no objeto feitas através object3
são refletidas em usos subsequentes do object4
. Como os objetos baseados em classes são referidos por referência, as classes são conhecidas como tipos de referência.
Construtores e inicialização
As seções anteriores introduziram a sintaxe para declarar um tipo de classe e criar uma instância desse tipo. Ao criar uma instância de um tipo, você deseja garantir que seus campos e propriedades sejam inicializados com valores úteis. Há várias maneiras de inicializar valores:
- Aceitar valores padrão
- Inicializadores de campo
- Parâmetros do construtor
- Inicializadores de objeto
Cada tipo .NET tem um valor padrão. Normalmente, esse valor é 0 para tipos de números e null
para todos os tipos de referência. Você pode confiar nesse valor padrão quando for razoável em seu aplicativo.
Quando o padrão .NET não é o valor correto, você pode definir um valor inicial usando um inicializador de campo:
public class Container
{
// Initialize capacity field to a default value of 10:
private int _capacity = 10;
}
Você pode exigir que os chamadores forneçam um valor inicial definindo um construtor responsável por definir esse valor inicial:
public class Container
{
private int _capacity;
public Container(int capacity) => _capacity = capacity;
}
A partir do C# 12, você pode definir um construtor primário como parte da declaração de classe:
public class Container(int capacity)
{
private int _capacity = capacity;
}
Adicionar parâmetros ao nome da classe define o construtor primário. Esses parâmetros estão disponíveis no corpo de classe, que inclui seus membros. Você pode usá-los para inicializar campos ou em qualquer outro lugar onde eles sejam necessários.
Você também pode usar o required
modificador em uma propriedade e permitir que os chamadores usem um inicializador de objeto para definir o valor inicial da propriedade:
public class Person
{
public required string LastName { get; set; }
public required string FirstName { get; set; }
}
A adição da required
palavra-chave exige que os chamadores definam essas propriedades como parte de uma new
expressão:
var p1 = new Person(); // Error! Required properties not set
var p2 = new Person() { FirstName = "Grace", LastName = "Hopper" };
Herança de classe
As classes suportam totalmente a herança, uma característica fundamental da programação orientada a objetos. Ao criar uma classe, você pode herdar de qualquer outra classe que não esteja definida como sealed
. Outras classes podem herdar da sua classe e substituir os métodos virtuais da classe. Além disso, você pode implementar uma ou mais interfaces.
A herança é realizada usando uma derivação, o que significa que uma classe é declarada usando uma classe base da qual herda dados e comportamento. Uma classe base é especificada anexando dois pontos e o nome da classe base após o nome da classe derivada, da seguinte forma:
public class Manager : Employee
{
// Employee fields, properties, methods and events are inherited
// New Manager fields, properties, methods and events go here...
}
Quando uma declaração de classe inclui uma classe base, ela herda todos os membros da classe base, exceto os construtores. Para obter mais informações, consulte Herança.
Uma classe em C# só pode herdar diretamente de uma classe base. No entanto, como uma classe base pode herdar de outra classe, uma classe pode herdar indiretamente várias classes base. Além disso, uma classe pode implementar diretamente uma ou mais interfaces. Para obter mais informações, consulte Interfaces.
Uma classe pode ser declarada como abstract
. Uma classe abstrata contém métodos abstratos que têm uma definição de assinatura, mas nenhuma implementação. As classes abstratas não podem ser instanciadas. Eles só podem ser usados através de classes derivadas que implementam os métodos abstratos. Por outro lado, uma classe selada não permite que outras classes derivem dela. Para obter mais informações, consulte Classes abstratas e seladas e Membros da classe.
As definições de classe podem ser divididas entre diferentes arquivos de origem. Para obter mais informações, consulte Classes e métodos parciais.
Especificação da linguagem C#
Para obter mais informações, consulte a Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso do C#.