Dane instancji a dane statyczne
Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 15 z 70.
Teraz, gdy rozumiesz składowe statyczne, wyjaśnijmy, kiedy używać danych instancji, a kiedy danych statycznych. Ta decyzja wpływa na to, jak Twoja klasa przechowuje i udostępnia informacje.
Dane instancji należą indywidualnie do każdego obiektu. Każdy obiekt otrzymuje własną kopię, a zmiany w jednym obiekcie nie wpływają na pozostałe:
public class BankAccount
{
public string Owner { get; set; } // Instancja - unikalna dla każdego konta
public decimal Balance { get; set; } // Instancja - unikalna dla każdego konta
}Każde konto BankAccount ma własnego właściciela i saldo. To ma sens, ponieważ na różnych kontach znajdują się różne kwoty należące do różnych osób.
Dane statyczne należą do samej klasy i są współdzielone przez wszystkie jej instancje:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // Statyczne - takie samo dla wszystkich
public static int TotalAccounts = 0; // Statyczne - zlicza wszystkie konta
public string Owner { get; set; }
public decimal Balance { get; set; }
}Oprocentowanie dotyczy każdego konta jednakowo, więc powinno być statyczne. Licznik wszystkich kont śledzi informacje dotyczące całej klasy, a nie dane poszczególnych kont.
Prosta zasada: jeśli dane opisują konkretny obiekt, uczyń je instancyjnymi. Jeśli opisują całą klasę lub powinny być współdzielone, uczyń je statycznymi. Nieprawidłowe ich łączenie prowadzi do błędów, w których dane nieoczekiwanie zmieniają się między obiektami lub są niedostępne wtedy, gdy są potrzebne.
Wyzwanie
ŁatwyZbudujmy tracker sesji gry, który pokazuje różnicę między danymi należącymi do poszczególnych graczy a danymi współdzielonymi przez całą grę.
Utworzysz dwa pliki, aby uporządkować kod:
Player.cs: Zdefiniuj klasęPlayerw przestrzeni nazwGameSession. Każdy gracz ma własną nazwę użytkownikaUsername(string) i wynikScore(int) — te wartości są unikalne dla każdego gracza. Klasa powinna również śledzić informacje dotyczące wszystkich graczy: pole statyczneGameName(string), które przechowuje nazwę gry, w którą wszyscy grają, oraz pole statyczneTotalPlayers(int), które zlicza, ilu graczy dołączyło. Dodaj konstruktor, który przyjmuje nazwę użytkownika i wynik początkowy oraz automatycznie zwiększa łączną liczbę graczy. Dodaj metodę statycznąSetGameName(string name), aby ustawić nazwę gry.Program.cs: W pliku głównym skonfiguruj grę i utwórz graczy na podstawie danych wejściowych. Najpierw ustaw nazwę gry, a następnie utwórz dwóch graczy i wyświetl ich indywidualne informacje wraz ze współdzielonymi danymi gry.
Otrzymasz pięć danych wejściowych:
- Nazwę gry
- Nazwę użytkownika pierwszego gracza
- Wynik początkowy pierwszego gracza
- Nazwę użytkownika drugiego gracza
- Wynik początkowy drugiego gracza
Wyświetl wynik w tym formacie:
Game: {GameName}
Player: {Username}, Score: {Score}
Player: {Username}, Score: {Score}
Total Players: {TotalPlayers}Na przykład, jeśli danymi wejściowymi są BattleArena, DragonSlayer, 1500, ShadowNinja i 2200, wynik powinien wyglądać tak:
Game: BattleArena
Player: DragonSlayer, Score: 1500
Player: ShadowNinja, Score: 2200
Total Players: 2Zastanów się, które dane powinny być instancyjne (różne dla każdego gracza), a które statyczne (współdzielone przez wszystkich graczy). Nazwa gry i łączna liczba graczy opisują całą sesję, natomiast nazwa użytkownika i wynik są unikalne dla każdej osoby.
Spróbuj swoich sił
using System;
namespace GameSession
{
class Program
{
public static void Main(string[] args)
{
// Wczytaj dane wejściowe
string gameName = Console.ReadLine();
string username1 = Console.ReadLine();
int score1 = Convert.ToInt32(Console.ReadLine());
string username2 = Console.ReadLine();
int score2 = Convert.ToInt32(Console.ReadLine());
// TODO: Ustaw nazwę gry za pomocą metody statycznej
// TODO: Utwórz dwa obiekty Player na podstawie danych wejściowych
// TODO: Wypisz wynik w wymaganym formacie
// Gra: {GameName}
// Gracz: {Username}, Wynik: {Score}
// Gracz: {Username}, Wynik: {Score}
// Total Players: {TotalPlayers}
}
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrznePrzestrzenie nazw i dyrektywyWprowadzenie do klas i obiektówSłowo kluczowe „this”Metody i parametryPola a właściwościKonstruktoryInicjalizatory obiektówPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawowa składnia dziedziczenia (:)Słowo kluczowe 'base'Słowa kluczowe virtual i overrideKlasy sealedBazowa klasa 'object'Powtórzenie – hierarchia pracowników7Zaawansowane funkcje
Przeciążanie operatorówIndeksery (this[])Nadpisywanie ToString()Metody rozszerzającePodsumowanie – własna lista2Właściwości i składowe statyczne
Właściwości automatyczneWłaściwości tylko do odczytu i zapisuPola i metody statyczneKlasy statyczneSkładowe z ciałem wyrażeniowym5Polimorfizm i interfejsy
Polimorfizm czasu kompilacji a czasu wykonaniaInterfejs a klasa abstrakcyjnaWiele interfejsówJawne implementowanie interfejsówRzutowanie w górę i w dółPowtórka — kalkulator kształtów8Zaawansowane koncepcje OOP
Kompozycja zamiast dziedziczeniaTypy generyczne (klasy i metody)Delegaty i zdarzeniaAtrybuty i refleksjaIDisposable i instrukcja usingPodstawy wstrzykiwania zależności11Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu3Architektura klas
Dane instancji a dane statyczneSłowa kluczowe 'readonly' i 'const'Pola zapasowePowtórzenie — menedżer kont bankowych6Hermetyzacja
Modyfikatory dostępuWłaściwości w hermetyzacjiImplementacja ukrywania danychWzorce niezmiennościPowtórka — dane studentów9Argumenty zmiennej liczby
Słowo kluczowe „params”Parametry opcjonalneArgumenty nazwanePrzeciążanie metodPoćwicz samodzielnie: Kompilator C# online