[KURS C#] Właściwe właściwości

Do tej pory do przechowywania i modyfikowania danych kont bankowych wykorzystywaliśmy zmienne i metody. I było nam z tym dobrze. Jednak po zapoznaniu się z modyfikatorami dostępu i hermetyzacją powinna Ci przyjść do głowy pewna myśl.

Skoro powinniśmy maksymalnie ograniczać dostęp do rzeczy znajdujących się w klasie to nie możemy tak po prostu oznaczać ich jako publiczne! Co prawda dzięki temu możemy odczytać wartość z jakiejś zmiennej, ale przecież nic nie stoi na przeszkodzie żeby w innym miejscu ktoś zmienił tą wartość. W końcu jest publiczna, prawda?

Prawda. Dlatego dobrym pomysłem będzie pewnie dodanie publicznej metody, która zwróci nam wartość zmiennej, ale już sama zmienna będzie prywatna. Ewentualnie będziemy mieli jakąś funkcję, która ustawi nam wartość tej zmiennej, ale w określony sposób. Świetny pomysł! W końcu funkcje w klasie mają dostęp do znajdujących się tam zmiennych niezależnie od tego czy są publiczne czy prywatne.

Funkcje, które służą do tego aby zwrócić wartość albo ją ustawić nazywamy zazwyczaj getterami i setterami (od angielskich get i set). Są one pomocne kiedy właśnie np. chcemy ograniczyć możliwość zmiany wartości jakiejś zmiennej, ale jednocześnie dać możliwość używania jej wartości na zewnątrz klasy. Ewentualnie jeżeli chcemy jakoś modyfikować wartość przed zwróceniem albo ustawieniem nowej.

Na szczęście twórcy języka C# pomyśleli, że jest to często wykorzystywany pomysł i udostępnili bardzo pomocną „nakładkę”. Nazywa się ona właściwości.

Kurs w formie tekstowej nie jest tym czego szukasz? Świetnie! Bo z kodem CHCE_WIECEJ można uzyskać dostęp do kursu video uczącego podstaw języka C# 15% taniej! Kurs zawiera wiedzę z poniższego kursu i jeszcze więcej! Sprawdź na kurs-szarpania.pl!

Właściwie co to?

Właściwości są jednym z tych elementów, które sprawiają, że programowanie jest dużo przyjemniejsze bo obudowują często wykorzystywaną strukturę w coś prostszego. W tym wypadku mamy połączenie prywatnej zmiennej i publicznej lub prywatnej metody dającej dostęp do tej zmiennej.

Prosty przykład:

Chcemy aby jakaś wartość w klasie mogła być pobrana w innym miejscu. Ale jednocześnie nie mamy powodu żeby dawać możliwość jej zmiany poza tą klasą. Dlatego w powyższym kodzie samą zmienną robimy prywatną, żeby przypadkiem nikt się do niej bezpośrednio nie dobrał. Funkcję, która ustawia tą wartość również robimy prywatną – będzie dostępna tylko wewnątrz klasy, np. w konstruktorze. Metoda do pobrania tej wartości jest jednak publiczna bo nie mamy problemu z tym, żeby ktoś ją odczytywał i wykorzystywał do swoich niecnych celów.

A co jeśli Ci powiem, że taki sam efekt osiągniemy zapisując wszystko w ten sposób:

A nawet lepiej,  bo w nowszych wersjach języka C# jeżeli get albo set jest prywatny to nie musimy go pisać:

Tak oto wyglądają właściwości. W ten sposób załatwiliśmy sprawę prywatnej zmiennej, publicznego gettera i prywatnego settera.

Trzeba jedynie pamiętać, że ta druga postać ma pewne ograniczenie. Chodzi o to, że nie wpisując w ogóle seta możemy ustawić wartość takiej zmiennej jedynie w konstruktorze. Jeżeli chcielibyśmy ją zmieniać w innych funkcjach klasy to musimy zastosować pierwszą postać z jawnie podanym prywatnym setterem.

Zabezpieczamy bank

Z tą wiedzą wróćmy więc do naszej aplikacji bankowej. Mamy klasę Account, która odpowiada za przechowywanie informacji o kontach. A co się w niej dzieje?

Wszystkie dane publiczne! Ok, potrzebujemy móc z nich korzystać. Jednak przez to nie ma problemu, żeby w dowolnym miejscu w aplikacji je zmodyfikować w obiekcie tej klasy!

Wyobrażasz sobie, że ktokolwiek w banku może od tak wziąć i zmienić Twoje dane np. w przelewie? Albo zmienić stan Twojego konta po prostu wpisując nowy? Absolutnie nie!

Pierwszym rozwiązaniem jakie byśmy jeszcze do niedawna zastosowali to była by publiczna metoda do pobierania tych wartości, a one same były by prywatne. Jednak uzbrojeni w zdobytą przed chwilą wiedzę możemy ułatwić sobie życie i zastosować właściwości zamiast samych zmiennych.

Zamiast:

Wpisujemy:

I tak dla wszystkich pól w klasie. Ostatecznie będzie ona wyglądać tak jak poniżej (usunąłem metody dla poprawienia czytelności):

Co zyskaliśmy?

Dzięki tej prostej zmianie bez pisania dodatkowych metod dla każdej wartości zapewniliśmy, że nadal będzie można odczytać tą wartość poza klasą. Jednocześnie jakakolwiek modyfikacja będzie możliwa tylko wewnątrz tej klasy.

Pod spodem nadal jest dodawana zmienna i funkcja. Jednak zastosowanie właściwości pozwoliło skrócić zapis i osiągnąć ten sam efekt jednak z zachowaniem dużo większej czytelności.

A coś więcej?

Jednak to co rozbiliśmy powyżej to tylko część możliwości właściwości. Chociaż nie da się ukryć, że najczęściej wykorzystywana.

Coś dostępne, coś ukryte

Kolejna opcja to oczywiście dodanie innych modyfikatorów dostępu. Ważne żeby zapamiętać, że getter i setter, jeżeli nie podamy przy nich modyfikatorów dostępu to przyjmują taki modyfikator jak ma cała właściwość.

Czyli jeżeli nasza właściwość jest publiczna to get bez dodatkowego modyfikatora też jest publiczny.

Nie ma też problemu, żeby setter był publiczny:

Albo możemy mieć całą właściwość chronioną:

Albo właściwość i getter chronione ale setter dostępny tylko w konstruktorze:

Mała zmiana

Inną możliwością jest faktyczne skorzystanie z faktu, że getter i settermetodami. Bo to, że przedstawiony powyżej sposób jest krótki i tylko ustawia lub pobiera wartość to wiemy. Ale możemy też dopisać jakąś logikę we właściwościach. Jednak kiedy to robimy to tracimy to, że automatycznie dodaje nam się prywatna zmienna pod spodem. Także jeżeli chcielibyśmy aby pobierana wartość była dwukrotnie większa niż faktycznie zapisana to możemy to zrobić w ten sposób:

Jak widać musieliśmy tutaj dodać sami zmienną, która przechowuje wartość. Podobnie możemy zrobić dodając własny setter:

Wtedy korzystamy ze słowa kluczowego value, które reprezentuje wartość jaką próbujemy przypisać do właściwości.

Jeżeli dopisujemy jakiś kod w którejś z metod właściwości to niestety w drugiej z nich również musimy jawnie napisać zwracanie albo ustawianie wartości zmiennej. Jednak ten sposób wykorzystania właściwości jest dużo rzadziej używany, co nie znaczy, że nie warto go poznać.

W takim przypadku właściwości są jedynie skróconym zapisem funkcji getSomething() i setSomething().

Właściwe podejście

Jak widzisz korzystanie z właściwości pozwala w prostszy sposób kontrolować dostęp do wartości w klasie. Dzięki temu zapewniamy sobie w prostszy sposób hermetyzację klasy.

Od teraz prawdopodobnie dużo częściej będziesz korzystał z właściwości zamiast ze zmiennych w klasach. Jednak absolutnie nie jest to jednoznacznie najlepsze podejście bo oba mają swoje wady i zalety i nie zawsze potrzebujemy stosować właściwości, zwłaszcza jeżeli mówimy o prywatnych wartościach.

 

Poprzednia lekcja – nie wszystko publiczne

Następna lekcja – gwarantowany zestaw złączy

Spis treści

Wiesz, że możesz mnie znaleźć nie tylko na tym blogu?

Wszystkie miejsca, w których udzielam się w internecie poznacz na stronie codewin.pl.

Szukasz książek dla programistów i jednocześnie chcesz wesprzeć tego bloga? Sprawdź ofertę wydawnictwa Helion klikając w TEN LINK.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *