1. Klasa a obiekt
Aby zrozumieć różnicę pomiędzy klasą a obiektem, możemy spojrzeć na te dwa pojęcia jak na przykład wzięty z życia. Mamy dajmy na to samochód. Samochodów może być dużo, mogą mieć różne marki, różne kolory oraz różnych właścicieli. Taki właśnie samochód jest klasą - wiemy jakie ma parametry, lecz nie znamy ich wartości. Spośród wielu samochodów wybieramy sobie jeden, a właściwie tworzymy go. Chcemy aby taki samochód przykładowo był Fordem w kolorze czarnym posiadanym przez nas. Ten właśnie Ford jest obiektem - posiada nadane jakieś wartości i możemy wykonywać na nim dalsze operacje.
Klasy są typami referencyjnymi i ich zawartość jest zawsze tworzona na stercie. W niektórych wypadkach klasa zawiera tak niewielką ilość danych , że zarządzanie nimi na stercie jest nieopłacalne. W takich wypadkach lepiej użyć struktury.
Struktura jest typem wartościowym czyli jej miejsce jest na stosie.
Chociaż jeśli struktura jest duża to lepiej stosować klasy.
Podobnie jak klasy struktura może mieć własne pola i metody……oraz w pewnym specjalnym wypadku konstruktor.
Podstawową różnicą pomiędzy strukturą i klasą jest to, że struktury nie obsługują dziedziczenia.
Jedną z najważniejszych cech dobrego programowania obiektowego jest dostarczenie użytkownikowi takiego programu, który będzie nadawał się do dalszej rozbudowy bez poprawy tego, co już zostało napisane. Jak taki cel osiągnąć? Po prostu poprzez zaprojektowanie klasy w taki sposób, aby zabezpieczyć ją przed ingerencją z zewnątrz. Innymi słowy, należy ukryć wewnętrzną strukturę definiowanej przez nas klasy. Taki mechanizm nazywamy hermetyzacją. Często pojęcie to określane jest enkapsulacją, bądź po prostu ukrywaniem danych.
4. Abstrahowanie
Język C# umożliwia programiście tworzenie wielu metod o tej samej nazwie w ramach jednej klasy. Aby program wiedział, której metody użyć w danym momencie, muszą one się różnić typem lub liczbą argumentów. Taki sposób tworzenia metod nazywa się przeciążaniem
6. Konstruktor
Konstruktor to innymi słowami metoda tworząca obiekt danej klasy i (opcjonalnie) inicjująca jej pola.
7. Konstruktor domyślny
Tworzony jest przez kompilator w przypadku nie utworzenia konstruktora przez programistę.
Konstruktor, który można wywołać bez podawania jakichkolwiek parametrów.
8. Właściwości
Właściwości to specjalna konstrukcja języka C# która symuluje zachowanie pól klasy lub struktury, a w rzeczywistości jest trochę podobna do funkcji.
Oferuje elastyczny mechanizm do odczytu, zapisu lub obliczenia pola typu private. Umożliwia łatwy dostęp do danych promując przy okazji bezpieczeństwo i elastyczność metod.
9. Właściwości automatyczne
10. Readonly
Słowo kluczowe readonly to modyfikator, który można zastosować na polach. Gdy deklaracja pola zawiera modyfikator readonly, przypisania do pól mogą występować wyłącznie jako część tej deklaracji, lub w konstruktorze tej samej klasy.
11. Const vs Readonly
Const:
Nie może być deklarowane z modyfikatorem static – stanowiłoby to pewną nadmiarowość ponieważ stałe odwołują się w końcu do całej klasy a nie instancji (skoro nie mogą być zmodyfikowane nie ma sensu istnienia kopii dla każdej z instancji).
Wartość jest przypisywana w czasie kompilacji.
Wartość można ustawiać wyłącznie w deklaracji (co jest następstwem reguły 2).
Wartość oznaczona modyfikatorem const może być wykorzystywana w warunku case constant (switch-case)
Readonly:
Może być poprzedzone modyfikatorem static.
Przetwarzane na poziomie runtime.
Można inicjalizować zarówno z poziomu deklaracji jak i konstruktora.
12. Indeksatory
13. Pola statyczne
Czasami zachodzi potrzeba dodania elementu, który jest zwiazany z klasą, ale nie z konkretną instancją tej klasy. Możemy wtedy stworzyć element statyczny. Element statyczny jest właśnie elementem, który jest powiązany z klasą, a nie z obiektem tej klasy, czyli np. statyczna metoda nie może się odwołać do niestatycznej zmiennej lub funkcji.
14. Metody statyczne
W programowaniu obiektowym jest to metoda klasy, która nie jest wywoływana w kontekście żadnego konkretnego obiektu tej klasy. Metody statyczne z reguły służą do obsługi składowych statycznych klas.
Właściwości:
W ciele metody statycznej, z racji tego iż nie jest wywoływana na rzecz konkretnego obiektu, nie można odwoływać się do składowych niestatycznych. Nie można więc użyć wskaźnikathis, self, Me itp.
Metoda statyczna może wywołać jedynie inne metody statyczne w swojej klasie lub odwoływać się jedynie do pól statycznych w swojej klasie. Dostęp do pól i metod obiektów przekazywanych jako parametry czy też obiektów i funkcji globalnych następuje tak samo jak w zwykłej funkcji, jednak w przypadku obiektów własnej klasy ma dostęp do składowych prywatnych.
Metoda statyczna nie może być metodą wirtualną.
15. Konstruktor statyczny
Konstruktor statyczny jest używany do wykonywania szczególnych działań, które należy wykonać tylko raz. Jest wywoływany automatycznie zanim wystąpi odwołanie do jakiegokolwiek pola statycznego.
16. Klasy statyczne
Przykładem klasy statycznej jest np. klasa Math , która zawiera wszystkie potrzebne funkcje matematyczne jak np. cosinus. Do ich użycia klasa nie musi być zadeklarowana.
Na pewno zauważysz ,że nie wszystkie metody należą do instancji klasy; są to metody, które wykonują swoje cele w sposób niezależny od specyfikacji zainicjalizowanej klasy. To są metody statyczne.
17. Dziedziczenie
Dziedziczenie to kluczowy mechanizm obiektowości. Dziedziczenie pozwala na powielanie funkcjonalności wobec różnych klas w ten sposób nie musimy pisać ciągle samego kodu.
Dziedziczenie w programowaniu jest bardziej o związkach pomiędzy klasami np. jedna może zawierać się w drugiej. Aby to uprościć powiedzmy , że klasy są jak kategorie . Ssaki to duża kategoria zwierząt, w której zawiera się też człowiek. Wszystkie ssaki mają pewne cechy wspólne jak: faza snu Rem, czy sposób karmienia potomstwa. Jednak każdy odrębny ssak ma swoje cechy specjalne.
Drugi przykład. Klasa figury opisuje cechy wspólne klas jak prostokąt, czy trójkąt ponieważ są one też figurami. Prostokąt i trójkąt jednak mają swoje cechy specjalne. Ustalanie cech wspólnych poszczególnych klas daje sens tworzenia klas bazowych. Nie chciałbyś dla każdej figury, czy ssaka powielać tych samych cech, które występują. Jest to esencja modelowania klasy. Zarządzenie taką aplikacją jest sporo łatwiejsze ponieważ w wypadku dodania nowej metody dla wszystkich ssaków, czy figury nie trzeba byłoby robić kopiuj/wklej dla każdej klasy po kolei.
18. Modyfikatory dostępu
W języku C# możemy wyróżnić cztery słowa kluczowe określane mianem modyfikatorów dostępu:
Dany element nie może być opatrzony więcej niż jednym modyfikatorem. Wyjątkiem jest tutaj połączenie modyfikatorów protected oraz internal.
Modyfikatory dostępu mają ścisły związek z hermatyzacją, czyli ukrywaniem elementów składowych klas. Umożliwiają określenie dostępu do danego elementu z zewnątrz klasy. Dzięki modyfikatorom jesteśmy w stanie ukryć niektóre pola, właściwości czy metody przed użytkownikiem klas. Ten nie ma wówczas dostępu do tych składowych.
19. New
Słowo kluczowe new w Javie i C# wraz z wyrażeniem konstruktora stanowi wyrażenie tworzące obiekt. Wyrażenie to zwraca referencję do utworzonego obiektu. Jest to jedyne w tych językach dozwolone wyrażenie pozwalające utworzyć obiekt i obowiązuje również w wyrażeniach throw, przez po słowie throw praktycznie zawsze musi być słowo new.
Obiekt utworzony w ten sposób jest obiektem o nieokreślonej trwałości i istnieje przynajmniej tak długo, jak długo istnieją referencje do niego. Odzyskanie pamięci po "zgubionych" obiektach jest zapewnione przez odśmiecanie pamięci.
W Javie i C# ten sposób tworzenia obiektów jest jedynym sposobem tworzenia obiektów typów klasowych. W C# dodatkowo istnieje typ strukturalny, którego obiekty tworzy się tak, jak obiekty typów wbudowanych.
20. Base
Słowo kluczowe base to podobnie jak this odwołanie do klasy, ale w tym przypadku klasy bazowej o ile takowa jest. Podczas dziedziczenia często potrzebujemy dostać się do metod, pól, właściwości, które są częścią klasy bazowej, a w naszej klasie potomnej są pola o takiej samej nazwie. Dla kompilatora ważniejsze są zmienne z naszej klasy pochodnej, nie bazowej, ale jeżeli chcemy dostać się do pól i metod klasy bazowej użyjemy słowa base:
21. Polimorfizm
Mechanizmy pozwalające programiście używać wartości, zmiennych i podprogramów na kilka różnych sposobów. Inaczej mówiąc jest to możliwość wyabstrahowania wyrażeń od konkretnych typów.
Podczas pisania programu wygodnie jest traktować nawet różne dane w jednolity sposób. Niezależnie czy należy wydrukować liczbę czy napis, czytelniej (zazwyczaj) jest gdy operacja taka nazywa się po prostu drukuj, a nie drukuj_liczbę i drukuj_napis. Jednak napis musi być drukowany inaczej niż liczba, dlatego będą istniały dwie implementacje polecenia drukuj, ale nazwanie ich wspólną nazwą tworzy wygodny abstrakcyjny interfejs niezależny od typu drukowanej wartości.
Czasami nawet nie trzeba dostarczać różnych implementacji, przykładowo podczas implementacji stosu nie jest bardzo istotne, jakiego typu wartości będą na nim przechowywane. Można napisać ogólne algorytmy obsługujące stos i ewentualne ukonkretnienie pozostawić systemowi. Mechanizmy umożliwiające takie udogodnienia nazywane są właśnie polimorfizmem.
22. Metody wirtualne
Metody wirtualne pozwalają na przesłanianie (zastępowanie) metod w podklasach.
Do definiowania metody wirtualnej służy słowo kluczowe: virtual
Aby zasłonić metodę z klasy bazowej w klasie nadrzędnej należy zdefiniować funkcje ze słowem kluczowym override z dokładnie tą samą nazwą i parametrami.
Aby odwołać się do przesłoniętej metody należy użyć słowa kluczowego base.
Nie jest wymogiem przesłanianie metody wirtualnych w klasach nadrzędnych.
23. Virtual i override
24. Jaka jest różnica między przysłonięciem a nadpisaniem metody?
Przesłanianie metod – (pisanie ich nowej implementacji, od nowa lub dopisywanie rozszerzenia) aby przesłonić metodę metoda musi być virtualna. Potem w klasie potomnej piszemy identyczny nagłowek tylko zamiast virtual piszemy override (lub też piszemy override i naciskamy spacje, pokaże nam się lista metod które możemy przesłonić i automatycznie VS wygeneruje nam szablon.
25. Klasy abstrakcyjne
Klasy abstrakcyjne działają w podobny sposób jak interfejsy jednak ich metody mogą posiadać ciała i informacje. W klasie abstrakcyjnej możesz też zadeklarować metody wirtualne tak, aby klasa dziedzicząca po niej mogła podać swoją własną implementacje tej właśnie metody.
26. Metody abstrakcyjne
Klasa abstrakcyjna może zawierać metody abstrakcyjne. Co to jest metoda abstrakcyjna?
Metoda abstrakcyjna działa w podobny sposób jak metoda wirtualna poza tym ,że nie posiada swojego ciała.
Klasa dziedzicząca musi implementować tę metodę jest to zasada zbliżona do interfejsów. W innym przypadku zobaczysz błąd w czasie kompilacji.
Używając metod abstrakcyjnych twoja klasa abstrakcyjna może symulować działanie interfejsów.
Klasa nieabstrakcyjna nie może zawierać w sobie metod abstrakcyjnych.
27. Jaka jest różnica między metodą abstrakcyjną a metodą wirtualną
Metoda abstrakcyjna, czysta funkcja wirtualna , metoda objęta wiązaniem dynamicznym, której definicja znajduje się w klasie będącej pochodną klasy, w której znajduje się jej deklaracja.
Metoda abstrakcyjna to metoda, która nie ma implementacji (ciała) i jest zadeklarowana ze specyfikatorem abstract. Taka metoda może być deklarowana tylko w klasie abstrakcyjnej
Metody wirtualne to takie metody, dla których wiązanie odwołań z kodem programu następuje w fazie wykonania programu.
28. Interfejs
Interfejs – wg najprostszego języka - to kontrakt między użytkownikiem a klasą (lub strukturą, o której była mowa tydzień temu). Gdy dana klasa (struktura) obsługuje interfejs, to oznacza, że gwarantuje klientowi obsługę metody, właściwości czy też jakiegoś zdarzenia, które zostały wcześniej zdefiniowane w tym interfejsie. Innymi słowy, dzięki interfejsowi wymuszamy na klasie to co ona musi wykonywać, ale oczywiście nie określamy jak ma to robić.
29. Klasa abstrakcyjna vs Interfejs
W interfejsach wszystkie metody są abstrakcyjne, natomiast w klasie abstrakcyjnej można stworzyc metody posiadające ciało, jak i abstrakcyjne.
W php można dzidziczyć jedynie po jednej klasie, natomiat interfejsów, można implementować wiele. Ponadto interfejsy mogą dziedziczyc wiele interfejów
Klasa abstrakcyjna zazwyczaj jest mocno związana z klasami dziedziczącymi w sensie logicznym, czyli np. tworzymy klasę abstrakcyjną Planeta po której dziedziczą konkretne klasy planet (np Ziemia, Mars). Interfejs natomiast nie musi być już tak mocno związany z daną klasą, on określa jej cechy, np możesz stoworzyć interfejs Zniszczalny, który mówi że dany obiekt może zostać zniszczony. Taki interfejs możesz nadać zarówno klasą Planeta, Gwiazda, Budynek itp.
30. Typy generyczne
Pozwalają one sparametryzować klasę, przez co nie ma konieczności dokonywania później kłopotliwego rzutowania. Sam zapis typu generycznego to duża litera/litery ujęta w nawiasy ostre.
31. Delegaty
Delegaty (wywodzą się z wskaźników) dbają o bezpieczeństwo typów zwracanych obiektów i metod, na które wskazują. Te nowe typy danych zawieraja trzy ważne informacje:
adres metody, na którą wskazują
parametry tej metody
oraz zwracany typ danej metody
Deklaracje delegatów tworzymy podobnie jak zwykłe funkcje, poprzedzając je jedynie słowem kluczowym delegate
32. Wyrażenia lambda
Wyrażenia lambda pozwalają na uproszczenie zapisu do wymaganego minimum.
33. Zdarzenia
Zdarzenia są elementem, z którego korzystamy bardzo często, może nawet nie świadomie. Wyobraźmy sobie jakąkolwiek aplikację, do której obsługi wykorzystywana jest myszka. Jakiekolwiek kliknięcie lewym czy prawym przyciskiem myszy, często wywołuje jakąś akcję np. ukazanie menu kontekstowego. I to jest właśnie zdarzenie.