Menu
CoddyTech

Właściwości w hermetyzacji

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 32 z 70.

Właściwości są podstawowym narzędziem do implementowania enkapsulacji w C#. Zamiast udostępniać pola bezpośrednio, opakowujesz je właściwościami, które kontrolują sposób dostępu do danych i ich modyfikowania.

Wzorzec łączy pole prywatne z właściwością publiczną, która zawiera walidację lub logikę w swoich akcesorach:

public class Temperature
{
    private double celsius;
    
    public double Celsius
    {
        get { return celsius; }
        set
        {
            if (value < -273.15)
                celsius = -273.15;  // Minimum to zero bezwzględne
            else
                celsius = value;
        }
    }
}

Teraz kod zewnętrzny nie może ustawić niemożliwej temperatury. Właściwość działa jak strażnik, dbając o to, by Twój obiekt zawsze pozostawał w prawidłowym stanie. To enkapsulacja w praktyce — dane wewnętrzne są chronione, a jednocześnie dostępne za pośrednictwem kontrolowanego interfejsu.

Możesz również używać właściwości do obliczania wartości lub wywoływania efektów ubocznych:

public double Fahrenheit
{
    get { return celsius * 9 / 5 + 32; }
    set { celsius = (value - 32) * 5 / 9; }
}

Świat zewnętrzny widzi dwie właściwości, ale wewnętrznie istnieje tylko jedno pole. Właściwości pozwalają zmieniać szczegóły implementacji bez psucia kodu korzystającego z Twojej klasy — to kluczowa zaleta prawidłowej enkapsulacji.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system ewidencji produktów, który wykorzystuje właściwości do ochrony integralności danych. Utworzysz klasę, w której ceny nigdy nie będą ujemne, a ilości zawsze będą mieścić się w prawidłowych zakresach — zademonstrujesz w ten sposób, jak właściwości pełnią funkcję strażników danych.

Uporządkujesz kod w dwóch plikach:

  • Product.cs: Utwórz klasę Product w przestrzeni nazw Inventory, która zarządza informacjami o produkcie i sprawdza poprawność danych za pomocą właściwości. Produkt powinien mieć:
    • Prywatne pole price (decimal) i publiczną właściwość Price, która gwarantuje, że cena nigdy nie będzie niższa niż 0 — jeśli ktoś spróbuje ustawić ujemną cenę, zamiast niej powinna zostać zapisana wartość 0
    • Prywatne pole quantity (int) i publiczną właściwość Quantity, która utrzymuje wartości w zakresie od 0 do 1000 — wartości poniżej 0 stają się równe 0, a wartości powyżej 1000 stają się równe 1000
    • Publiczną, automatycznie implementowaną właściwość Name (string)
    • Obliczaną właściwość tylko do odczytu TotalValue, która zwraca Price * Quantity
    Dodaj konstruktor, który przyjmuje nazwę, cenę i ilość (w tej kolejności) oraz ustawia wszystkie wartości za pomocą właściwości, tak aby zastosować walidację.
  • Program.cs: W pliku głównym utwórz obiekt Product, używając wartości wejściowych. Następnie spróbuj zmodyfikować cenę i ilość za pomocą dodatkowych wartości wejściowych, które mogą być nieprawidłowe. Wyświetl stan produktu po utworzeniu oraz po każdej modyfikacji, aby zobaczyć, jak właściwości chronią dane.

Otrzymasz pięć danych wejściowych:

  • Nazwa produktu
  • Cena początkowa (decimal)
  • Początkowa ilość (liczba całkowita)
  • Nowa cena do ustawienia (decimal, może być ujemna)
  • Nowa ilość do ustawienia (liczba całkowita, może być poza zakresem)

Wyświetl wynik w następującym formacie:

After creation:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
After modifications:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}

Na przykład, jeśli dane wejściowe to Laptop, 999.99, 50, -100 i 1500, wynik powinien wyglądać tak:

After creation:
Laptop: Price=999.99, Qty=50, Total=49999.50
After modifications:
Laptop: Price=0, Qty=1000, Total=0

Zwróć uwagę, że ujemna cena zmieniła się na 0, a ilość 1500 została ograniczona do 1000. Właściwości chronią obiekt przed nieprawidłowymi stanami — właśnie tak działa enkapsulacja!

Spróbuj swoich sił

using System;
using Inventory;

class Program
{
    public static void Main(string[] args)
    {
        // Wczytaj dane wejściowe
        string name = Console.ReadLine();
        decimal initialPrice = Convert.ToDecimal(Console.ReadLine());
        int initialQuantity = Convert.ToInt32(Console.ReadLine());
        decimal newPrice = Convert.ToDecimal(Console.ReadLine());
        int newQuantity = Convert.ToInt32(Console.ReadLine());

        // TODO: Utwórz Product, używając wartości początkowych
        
        // TODO: Wypisz stan produktu po utworzeniu
        Console.WriteLine("After creation:");
        // Format wyjściowy: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
        
        // TODO: Zmień cenę i ilość, używając nowych wartości
        
        // TODO: Wypisz stan produktu po zmianach
        Console.WriteLine("After modifications:");
        // Format wyjściowy: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online