Wprowadzenie do klas

Typy odwołań

Typ, który jest zdefiniowany jako typ classodwołania. W czasie wykonywania, gdy deklarujesz zmienną typu odwołania, zmienna zawiera wartość null do momentu jawnego utworzenia wystąpienia klasy przy użyciu new operatora lub przypisania do niego obiektu zgodnego typu, który mógł zostać utworzony w innym miejscu, jak pokazano w poniższym przykładzie:

//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;

Po utworzeniu obiektu wystarczająca ilość pamięci jest przydzielana na zarządzanym stercie dla tego określonego obiektu, a zmienna przechowuje tylko odwołanie do lokalizacji określonego obiektu. Pamięć używana przez obiekt jest odzyskiwane przez funkcję automatycznego zarządzania pamięcią CLR, która jest nazywana odzyskiwaniem pamięci. Aby uzyskać więcej informacji na temat odzyskiwania pamięci, zobacz Automatyczne zarządzanie pamięcią i odzyskiwanie pamięci.

Deklarowanie klas

Klasy są deklarowane przy użyciu class słowa kluczowego, po którym następuje unikatowy identyfikator, jak pokazano w poniższym przykładzie:

//[access modifier] - [class] - [identifier]
public class Customer
{
   // Fields, properties, methods and events go here...
}

Opcjonalny modyfikator dostępu poprzedza class słowo kluczowe . Ponieważ public jest używana w tym przypadku, każda osoba może tworzyć wystąpienia tej klasy. Nazwa klasy jest zgodna ze class słowem kluczowym. Nazwa klasy musi być prawidłową nazwą identyfikatora języka C#. Pozostała część definicji to treść klasy, w której zdefiniowano zachowanie i dane. Pola, właściwości, metody i zdarzenia w klasie są określane zbiorczo jako składowe klasy.

Tworzenie obiektów

Chociaż są one czasami używane zamiennie, klasa i obiekt są różne rzeczy. Klasa definiuje typ obiektu, ale nie jest to sam obiekt. Obiekt jest konkretną jednostką opartą na klasie i czasami określany jako wystąpienie klasy.

Obiekty można tworzyć przy użyciu new słowa kluczowego , a następnie nazwy klasy, w następujący sposób:

Customer object1 = new Customer();

Po utworzeniu wystąpienia klasy odwołanie do obiektu jest przekazywane z powrotem do programisty. W poprzednim przykładzie object1 jest odwołaniem do obiektu opartego na metodzie Customer. To odwołanie odnosi się do nowego obiektu, ale nie zawiera samych danych obiektu. W rzeczywistości można utworzyć odwołanie do obiektu bez tworzenia obiektu w ogóle:

Customer object2;

Nie zalecamy tworzenia odwołań do obiektów, które nie odwołują się do obiektu, ponieważ próba uzyskania dostępu do obiektu za pośrednictwem takiego odwołania kończy się niepowodzeniem w czasie wykonywania. Odwołanie można utworzyć w celu odwoływania się do obiektu, tworząc nowy obiekt lub przypisując do niego istniejący obiekt, na przykład:

Customer object3 = new Customer();
Customer object4 = object3;

Ten kod tworzy dwa odwołania do obiektów, które odwołują się do tego samego obiektu. W związku z tym wszelkie zmiany wprowadzone w obiekcie object3 są odzwierciedlane w kolejnych zastosowaniach elementu object4. Ponieważ obiekty oparte na klasach są określane przez odwołanie, klasy są nazywane typami referencyjnymi.

Konstruktory i inicjowanie

W poprzednich sekcjach wprowadzono składnię, aby zadeklarować typ klasy i utworzyć wystąpienie tego typu. Podczas tworzenia wystąpienia typu należy upewnić się, że jego pola i właściwości są inicjowane do przydatnych wartości. Istnieje kilka sposobów inicjowania wartości:

  • Zaakceptuj wartości domyślne
  • Inicjatory pól
  • Parametry konstruktora
  • Inicjatory obiektów

Każdy typ platformy .NET ma wartość domyślną. Zazwyczaj ta wartość to 0 dla typów liczbowych i null dla wszystkich typów odwołań. Możesz polegać na tej wartości domyślnej, gdy jest rozsądna w aplikacji.

Jeśli wartość domyślna platformy .NET nie jest właściwa, możesz ustawić wartość początkową przy użyciu inicjatora pola:

public class Container
{
    // Initialize capacity field to a default value of 10:
    private int _capacity = 10;
}

Wywołania mogą wymagać podania wartości początkowej przez zdefiniowanie konstruktora odpowiedzialnego za ustawienie tej wartości początkowej:

public class Container
{
    private int _capacity;

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

Począwszy od języka C# 12, można zdefiniować podstawowy konstruktor w ramach deklaracji klasy:

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

Dodanie parametrów do nazwy klasy definiuje konstruktor podstawowy. Te parametry są dostępne w treści klasy, która zawiera jego składowe. Można ich używać do inicjowania pól lub gdziekolwiek indziej, gdzie są potrzebne.

Można również użyć required modyfikatora we właściwości i zezwolić obiektom wywołującym na używanie inicjatora obiektu w celu ustawienia początkowej wartości właściwości:

public class Person
{
    public required string LastName { get; set; }
    public required string FirstName { get; set; }
}

Dodanie required słowem kluczowym mandatów, które wywołujące muszą ustawić te właściwości w ramach new wyrażenia:

var p1 = new Person(); // Error! Required properties not set
var p2 = new Person() { FirstName = "Grace", LastName = "Hopper" };

Dziedziczenie klas

Klasy w pełni obsługują dziedziczenie, podstawową cechę programowania obiektowego. Podczas tworzenia klasy można dziedziczyć z dowolnej innej klasy, która nie jest zdefiniowana jako sealed. Inne klasy mogą dziedziczyć z klasy i przesłaniać metody wirtualne klasy. Ponadto można zaimplementować jeden lub więcej interfejsów.

Dziedziczenie odbywa się przy użyciu wyprowadzania, co oznacza, że klasa jest deklarowana przy użyciu klasy bazowej, z której dziedziczy dane i zachowanie. Klasa bazowa jest określana przez dołączenie dwukropka i nazwę klasy bazowej po nazwie klasy pochodnej w następujący sposób:

public class Manager : Employee
{
    // Employee fields, properties, methods and events are inherited
    // New Manager fields, properties, methods and events go here...
}

Gdy deklaracja klasy zawiera klasę bazową, dziedziczy wszystkie elementy członkowskie klasy bazowej z wyjątkiem konstruktorów. Aby uzyskać więcej informacji, zobacz Dziedziczenie.

Klasa w języku C# może bezpośrednio dziedziczyć tylko z jednej klasy bazowej. Jednak ponieważ klasa bazowa może dziedziczyć z innej klasy, klasa może pośrednio dziedziczyć wiele klas bazowych. Ponadto klasa może bezpośrednio implementować jeden lub więcej interfejsów. Aby uzyskać więcej informacji, zobacz Interfejsy.

Klasę można zadeklarować jako abstract. Klasa abstrakcyjna zawiera metody abstrakcyjne, które mają definicję podpisu, ale nie mają implementacji. Nie można utworzyć wystąpień klas abstrakcyjnych. Mogą być używane tylko za pomocą klas pochodnych, które implementują metody abstrakcyjne. Natomiast zapieczętowana klasa nie zezwala na uzyskiwanie z niej innych klas. Aby uzyskać więcej informacji, zobacz Klasy abstrakcyjne i zapieczętowane oraz składowe klas.

Definicje klas można podzielić między różne pliki źródłowe. Aby uzyskać więcej informacji, zobacz Klasy częściowe i metody.

Specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.