Udostępnij za pośrednictwem


Wprowadzenie do klas

Typy odwołań

Typ zdefiniowany jako class jest typem odwoł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 utworzonego gdzie indziej, 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 odzyskiwana przez funkcję automatycznego zarządzania pamięcią środowiska uruchomieniowego języka wspólnego (CLR), która jest nazywana garbage collection. Aby uzyskać więcej informacji na temat zbierania śmieci, zobacz Automatyczne zarządzanie pamięcią i zbieranie śmieci.

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 . Domyślny dostęp dla class typu to internal. 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 konkretnym bytem opartym na klasie i czasami nazywany 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();

Gdy zostanie utworzone wystąpienie 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że odnosić się do obiektu, przez utworzenie nowego obiektu lub przypisanie istniejącego obiektu, na przykład:

Customer object3 = new();
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 inicjalizacja

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
  • Inicjalizatory 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ą za pomocą inicjalizatora pola.

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

Możesz wymagać od wywołujących podania wartości początkowej poprzez zdefiniowanie konstruktora, który ją ustawia.

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. Parametry są dostępne w treści klasy, która zawiera jej 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ć wywołującym na użycie inicjalizatora 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 słowa kluczowego required wymaga, aby wywołujący musieli ustawić te właściwości jako część wyrażenia new.

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 Twojej klasy i przesłaniać jej metody wirtualne. 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 klasy 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#.