Wprowadzenie do modelowania rzeczywistości za pomocą klas. Omówienie składowych instancyjnych i statycznych, konstruktorów oraz właściwości.
Student demonstruje umiejętność projektowania klasy zawierającej różnorodne składowe, takie jak pola prywatne, publiczne właściwości oraz składowe statyczne. Zadanie pokazuje praktyczne zastosowanie konstruktorów instancyjnych i statycznych do zarządzania stanem obiektów oraz globalnymi licznikami systemowymi. Student rozumie różnicę między zachowaniem obiektowym a statycznym w kontekście platformy .NET.
Pracujesz nad systemem dla firmy logistycznej, który ma za zadanie monitorować bazę pojazdów dostawczych. Każdy pojazd musi posiadać unikalny numer rejestracyjny, markę oraz informację o aktualnym stanie licznika kilometrów. System musi automatycznie zliczać, ile pojazdów zostało zarejestrowanych w trakcie działania aplikacji, korzystając z mechanizmów statycznych. Dodatkowo wymagane jest zdefiniowanie stałej określającej maksymalną dopuszczalną ładowność dla standardowej floty. Konstruktor statyczny powinien zostać użyty do zainicjalizowania globalnych parametrów konfiguracyjnych systemu, które są wspólne dla wszystkich obiektów. Każdy nowy pojazd jest tworzony z zerowym przebiegiem, chyba że podczas rejestracji zostanie podana inna wartość początkowa. Program musi uniemożliwić ustawienie ujemnego przebiegu poprzez odpowiednią logikę we właściwościach klasy. Na koniec aplikacja generuje raport wyświetlający dane konkretnego pojazdu oraz globalną liczbę wszystkich aut w bazie. Całość projektu musi być czytelna i stanowić solidny fundament pod dalszy rozwój modułu logistycznego. Jest to krytyczny element architektury pozwalający na zachowanie spójności danych o zasobach firmy.
using System; class Pojazd { // Pola i stałe public const string WersjaSystemu = "2.0.4-LTS"; private static int licznikPojazdow; private decimal przebieg; // Auto-właściwości public string Marka { get; set; } public string Rejestracja { get; set; } // Właściwość z logiką walidacji public decimal Przebieg { get => przebieg; set { if (value >= 0) przebieg = value; else Console.WriteLine("Błąd: Przebieg nie może być ujemny!"); } } // Składowa statyczna - dostępna dla całej klasy public static int Licznik => licznikPojazdow; // Konstruktor statyczny - wywoływany raz przy pierwszym użyciu klasy static Pojazd() { licznikPojazdow = 0; Console.WriteLine("System floty: zainicjalizowano składowe statyczne."); } // Konstruktor instancyjny public Pojazd(string marka, string rejestracja) { Marka = marka; Rejestracja = rejestracja; licznikPojazdow++; } // Przeciążony konstruktor public Pojazd(string marka, string rejestracja, decimal przebiegStart) : this(marka, rejestracja) { Przebieg = przebiegStart; } } class Program { static void Main() { Console.WriteLine($"Wersja oprogramowania: {Pojazd.WersjaSystemu}"); Pojazd p1 = new Pojazd("Ford", "KR12345"); Pojazd p2 = new Pojazd("Iveco", "WA98765", 1500.50m); Console.WriteLine($"Zarejestrowano {Pojazd.Licznik} pojazdy."); Console.WriteLine($"Pojazd 1: {p1.Marka}, Przebieg: {p1.Przebieg} km"); Console.WriteLine($"Pojazd 2: {p2.Marka}, Przebieg: {p2.Przebieg} km"); } }
Zapoznanie studentów z podstawami tworzenia własnych typów danych w C#. Głównym celem jest zrozumienie relacji między polami klasy a jej zachowaniem (metodami) oraz opanowanie operacji na polach prywatnych.
Zlecono Ci stworzenie modułu do przeliczeń geometrycznych dla aplikacji projektowej. Musisz zdefiniować klasę o nazwie "Prostokat", która będzie w stanie przechowywać długości dwóch boków. Obiekt tej klasy powinien być odpowiedzialny za własne obliczenia, takie jak wyznaczanie pola powierzchni oraz obwodu figury. Pola przechowujące wymiary muszą być ukryte przed bezpośrednim dostępem z zewnątrz, aby zapewnić integralność danych (brak możliwości ustawienia boków o długości zero lub ujemnej bez kontroli). Program główny powinien umożliwiać utworzenie kilku różnych prostokątów o wymiarach podanych przez użytkownika w konsoli. Po wprowadzeniu danych, system ma wyświetlić kompletny zestaw informacji dla każdej z figur w czytelny sposób. Implementacja tej klasy jest wstępem do budowania bardziej złożonych silników rysujących i obliczeniowych w przyszłych modułach. Musisz wykazać, że Twoja klasa poprawnie zarządza swoimi właściwościami wewnętrznymi. Program powinien kończyć się podsumowaniem, w którym porównasz pola powierzchni dwóch utworzonych prostokątów. Jest to klasyczny przykład enkapsulacji logiki i danych w pojedynczym komponencie.
Opanowanie praktycznego zastosowania właściwości (properties) zamiast bezpośredniego dostępu do pól. Student uczy się implementować logikę biznesową wewnątrz akcesorów get oraz set, zapewniając bezpieczeństwo transakcyjne.
Budujesz uproszczony system do obsługi platformy bankowości elektronicznej. Twoim zadaniem jest stworzenie klasy "KontoBankowe", która bezpiecznie przechowuje numer konta (tylko do odczytu po utworzeniu) oraz aktualne saldo (dostępne do odczytu, ale chronione przed bezpośrednią modyfikacją). Wszystkie operacje finansowe, takie jak wpłaty i wypłaty środków, muszą odbywać się za pośrednictwem dedykowanych metod, które sprawdzają poprawność transakcji. Na przykład, system nie może pozwolić na wypłacenie kwoty większej niż aktualnie dostępne środki na koncie. Klasa powinna również posiadać właściwość określającą limit debetowy, który jest stały dla wszystkich kont typu podstawowego. Użytkownik programu w konsoli powinien móc wykonać serię operacji: sprawdzić stan konta, wpłacić pieniądze oraz spróbować wypłacić kwotę przekraczającą stan posiadania, aby przetestować systemy obronne. Program musi generować czytelne komunikaty o sukcesie lub przyczynie odrzucenia transakcji. Dzięki temu podejściu dane finansowe klienta pozostają spójne i chronione przed nieautoryzowaną zmianą. Finalnie system powinien pokazać historię operacji w skróconej formie lub aktualne podsumowanie po serii ruchów finansowych.
Zrozumienie koncepcji klas statycznych w C# oraz sytuacji, w których ich użycie jest uzasadnione. Student uczy się projektować biblioteki metod pomocniczych, które nie wymagają tworzenia instancji obiektu do działania.
Wyobraź sobie, że piszesz uniwersalną bibliotekę narzędziową dla naukowców, która zawiera przydatne konwertery jednostek miar. Zamiast tworzyć za każdym razem nowy obiekt kalkulatora, chcesz, aby metody były dostępne globalnie w całym programie. Twoim zadaniem jest stworzenie klasy statycznej o nazwie "Konwerter", która będzie posiadać metody do zamiany stopni Celsjusza na Fahrenheita oraz kilometrów na mile morskie. Klasa ta powinna również przechowywać publiczne, statyczne stałe, takie jak wartość liczby PI lub przelicznik mili. Użytkownik programu powinien mieć możliwość szybkiego wywołania tych metod bezpośrednio po nazwie klasy w metodzie Main. Program musi pobrać dane wejściowe od użytkownika, wykonać obliczenia za pomocą Twojej statycznej biblioteki i zwrócić wynik z precyzją naukową. Ważne jest, aby zrozumieć, że klasa statyczna nie może posiadać konstruktora instancyjnego ani zwykłych pól nie-statycznych. Implementacja tego zadania uczy poprawnych wzorców projektowych stosowanych przy budowie tzw. "utility classes" w środowisku .NET. Całość powinna być zorganizowana w prosty i logiczny sposób, ułatwiający reużywalność kodu w innych projektach.
Opanowanie mechanizmu przeciążania konstruktorów oraz efektywnego wykorzystania słowa kluczowego this do unikania powielania kodu inicjalizacyjnego. Student uczy się poprawnie zarządzać stanem początkowym obiektów klasy.
System HR nowo założonego startupu wymaga elastycznego sposobu dodawania nowych pracowników do bazy danych. Nie wszyscy pracownicy mają od razu przypisane stanowisko czy określone wynagrodzenie w momencie podpisywania wstępnych dokumentów. Musisz zaprojektować klasę "Pracownik", która pozwala na utworzenie obiektu na trzy różne sposoby. Pierwszy wariant wymaga podania tylko imienia i nazwiska (wynagrodzenie ustawiane jest na płacę minimalną). Drugi wariant pozwala podać imię, nazwisko oraz konkretne wynagrodzenie, jeśli jest ono znane od początku. Trzeci, najbardziej rozbudowany konstruktor, przyjmuje wszystkie dane wraz z nazwą działu, w którym osoba będzie pracować. Twoim celem jest połączenie tych konstruktorów w taki sposób, aby podstawowe przypisania działy się w jednym miejscu, a inne konstruktory jedynie „dopełniały” dane (tzw. constructor chaining). Program w konsoli powinien utworzyć trzech różnych pracowników, korzystając z każdego z dostępnych konstruktorów, a następnie wyświetlić ich dane jako sformatowane karty pracownicze. To zadanie uczy, jak projektować API klas, które jest przyjazne dla innych programistów i odporne na brakujące dane startowe.
Zrozumienie specjalnej roli konstruktora statycznego w inicjalizacji środowiska uruchomieniowego aplikacji. Student uczy się odróżniać inicjalizację danych wspólnych (klasowych) od danych specyficznych dla konkretnych instancji.
Budujesz zaawansowany "SystemKonfiguracyjny" dla aplikacji serwerowej, która przy starcie musi załadować pewne parametry globalne, takie jak adres serwera bazy danych oraz aktualna strefa czasowa. Te parametry są identyczne dla każdego modułu systemu i nie zmieniają się w trakcie jego działania. Twoim zadaniem jest stworzenie klasy, która przy pierwszej próbie użycia (np. odczytu dowolnego parametru) automatycznie wykona jednorazową konfigurację za pomocą konstruktora statycznego. Konstruktor ten ma symulować odczyt danych z pliku (poprzez wyświetlenie komunikatu w konsoli) i zainicjalizować statyczne pola klasy. Dodatkowo klasa powinna pozwalać na tworzenie obiektów reprezentujących konkretne sesje użytkowników, które posiadają własne, unikalne identyfikatory. Musisz wykazać, że moment wywołania konstruktora statycznego jest niezależny od tworzenia poszczególnych obiektów tej klasy. Wyświetl logi systemowe tak, aby było widać kolejność: najpierw inicjalizacja globalna, potem start konkretnych sesji. To zadanie ma kluczowe znaczenie dla zrozumienia cyklu życia aplikacji w modelu pamięciowym .NET. Program kończy się wyświetleniem parametrów, które zostały poprawnie załadowane tylko jeden raz.
Integracja wiedzy o właściwościach, tablicach oraz logice wewnątrz akcesorów set. Student uczy się projektowania obiektów, które nie tylko przechowują stan, ale również reagują na zmiany tego stanu w sposób inteligentny.
Jesteś inżynierem oprogramowania projektującym inteligentny termometr domowy (IoT). Urządzenie posiada klasę "Termometr", która przechowuje aktualną temperaturę, ale system wymaga, aby każda zmiana tej wartości była automatycznie zapisywana jako najwyższa zanotowana temperatura (rekord), jeśli nowa wartość jest większa od poprzedniej. Musisz wykorzystać właściwość C# do implementacji tej logiki: przy każdym przypisaniu nowej temperatury, program sprawdza, czy nie pobito rekordu. Dodatkowo termometr powinien informować, jeśli nowa temperatura przekracza bezpieczny zakres (np. powyżej 40 stopni Celsjusza) – informacja taka powinna być wypisana w konsoli jako ostrzeżenie. Użytkownik w pętli symuluje odczyty z sensora w ciągu godziny. Twoim zadaniem jest zapewnienie dodatkowej właściwości o nazwie "Srednia", która jest obliczana na bieżąco (lub po zakończeniu sesji) jako średnia z ostatnich trzech pomiarów zachowanych w małej tablicy wewnętrznej. To zadanie łączy wiedzę o enkapsulacji z prostymi algorytmami monitoringu procesów fizycznych. Finalny raport prezentuje aktualny odczyt, rekord historyczny oraz status bezpieczeństwa urządzenia. Program kończy się, gdy użytkownik wprowadzi specjalny kod wyłączający symulację sensora.