Jest to jeden z filarów programowania obiektowego. Ma ona za zadanie, dzięki zastosowaniu odpowiednich mechanizmów, ukrycie w obiekcie elementów, do których użytkownik nie powinien mieć dostępu. Nazywana jest też hermetyzacją. Zobaczmy przykład:
Stwórzmy prostą klasę Car, która posiada pola odpowiedzialne za przechowywanie informacji na temat: koloru samochodu, marki oraz ceny. Klasa będzie posiadać jedną metodę, która wypisze nam stan naszego obiektu na ekranie.

class Car {
    public string color;
    public string carBrand;
    public double price = 0;

    public void ViewInformation() {
        Console.WriteLine("Kolor samochodu: " + color);
        Console.WriteLine("Marka samochodu: " + carBrand);
        Console.WriteLine("Cena samochodu: " + price);
    }
}

W kodzie klienta mamy teraz bezpośredni dostęp do tych zmiennych:

using System;
class Car {
    public string color;
    public string carBrand;
    public double price = 0;

    public void ViewInformation() {
        Console.WriteLine("Kolor samochodu: " + color);
        Console.WriteLine("Marka samochodu: " + carBrand);
        Console.WriteLine("Cena samochodu: " + price);
    }
}
class Program {
    static void Main() {
        Car auto = new Car();
        auto.carBrand = "Fiat";
        auto.color = "black";
        auto.price = -120000;
        auto.ViewInformation();

        Console.ReadLine();
    }
}

Rezultat działania aplikacji:

cz1-2

Rys. Wyświetlenie stanu obiektu

Możemy w dowolny sposób przypisywać dane do pól w obiekcie, przez co nie odbywa się żadna walidacja danych i użytkownik może podać ujemną cenę samochodu.
Temat ten powiązany jest z modyfikatorami dostępu, omówię je dokładnie w innym wpisie, na chwilę obecną potrzebna jest nam wiedza na temat dwóch modyfikatorów:
– public- element jest dostępny z poziomu obiektu danej klasy.
– private- element jest dostępny jedynie w obrębie danej klasy.
W większości języków enkapsulację pól danej klasy realizuje się za pomocą ustawienia modyfikatora dostępu dla pola na private i stworzeniu publicznych metod odpowiedzialnych za zapis i odczyt wartości tej zmiennej.

Metody dostępu do pola klasy

Do przypisania lub odczytania wartości dla zmiennej prywatnej w klasie lub strukturze możemy użyć publicznych metod, które zwracają lub przypiszą wartość zmiennej prywatnej umieszczonej w danej klasie. Najczęściej nazwy tych funkcji mają przedrostki get oraz set. Dzięki nim możemy ustalić walidację wprowadzanych i zwracanych danych, zobaczmy przykład prostej klasy Car:

class Car {
    private string color;
    private string carBrand;
    private double price = 0;

    public void ViewInformation() {
        Console.WriteLine("Kolor samochodu: " + color);
        Console.WriteLine("Marka samochodu: " + carBrand);
        Console.WriteLine("Cena samochodu: " + price);
    }
}

Dopiszmy teraz do tej klasy publiczne metody, które będą przypisywać naszym zmiennym prywatnym wartości (metody set):

   public void SetColor(string color) {
        this.color = color;
    }
    public void SetCarBrand(string brand) {
        carBrand = brand;
    }
    public void SetCarPrice(double price) {
        this.price = price;
    }

Możemy teraz przypisywać wartości dla naszych zmiennych w metodach SetColor(string color) ,SetCarBrand(string brand) oraz SetCarPrice(double price).
Jesteśmy w stanie ustalić różne reguły, co do wartości przypisywanej przez użytkownika np. chcemy aby kolor samochodu był zawsze przechowywany w zmiennej color drukowanymi literami nie zależnie od tego jak wpisze go użytkownik:

  public void SetColor(string color){
           this.color = color.ToUpper();
        } 

Dodatkowo chcemy aby wartość pola price była zawsze dodania. Gdy użytkownik wpisze wartość ujemną powinna zostać ona zamieniona na wartość dodatnią. Zobaczmy:

public void SetCarPrice(double price) {
        if (price > 0)
            this.price = price;
        else
            this.price = (-1) * price;
    }

Teraz aby odczytać wartość musimy stworzyć metody, które będą nam je zwracać (metoday get):

public string GetColor() {
        return color;
    }
    public string GetCarBrand() {
        return carBrand;
    }
    public double GetPrice() {
        return price;
    }

W ten sposób mamy kontrolę nad naszymi zmiennymi. Walidujemy wybrane dane i w przypadku zmian w logice biznesowej wystarczy, że zmienimy metody odpowiadające za dostęp do pól. Nie musimy zmieniać kodu klienta.
W kodzie klienta do tych zmiennych odnosimy się w następujący sposób:
Cały kod programu:

using System;
class Car {
    private string color;
    private string carBrand;
    private double price = 0;

    public void SetColor(string color) {
        this.color = color.ToUpper();
    }
    public void SetCarBrand(string brand) {
        carBrand = brand;
    }
    public void SetCarPrice(double price) {
        if (price > 0)
            this.price = price;
        else
            this.price = (-1) * price;
    }
    public string GetColor() {
        return color;
    }
    public string GetCarBrand() {
        return carBrand;
    }
    public double GetPrice() {
        return price;
    }

    public void ViewInformation() {
        Console.WriteLine("Kolor samochodu: " + color);
        Console.WriteLine("Marka samochodu: " + carBrand);
        Console.WriteLine("Cena samochodu: " + price);
    }
}
class Program {
    static void Main() {
        Car auto = new Car();
        auto.SetCarBrand("Fiat");
        auto.SetCarPrice(-120000);
        auto.SetColor("black");
        auto.ViewInformation();
        Console.ReadLine();
    }
}

Oto rezultat:

cz1-2

Rys. Wyświetlenie stanu obiektu

Jak widzimy nasza metoda zadziałała prawidłowo i zapisała kolor samochodu drukowanymi literami oraz wprowadzona cena jest dodatnia.
Jeżeli chcemy aby któreś z pól było tylko do odczytu, wystarczy nie pisać publicznej metody, dzięki której przypiszemy wartość do prywatnej zmiennej. Natomiast jeżeli chcemy aby pole było tylko do zapisu, wystarczy nie implementować publicznej metody, która zwraca wartość zmiennej prywatnej.
W przypadku rozbudowanego systemu możemy sobie wyobrazić ile takich prostych funkcji musimy napisać. Z pomocą w języku C# przychodzą właściwości.