Klasy

Stronę tą wyświetlono już: 265 razy

Wstęp

Klasy w C# są typami referencyjnymi, co oznacza, że każda instancja klasy jest wskaźnikiem na jakiś adres pamięci, gdzie wszystkie pola oraz metody klasy się znajdują. Dzięki takiemu rozwiązaniu dużo szybciej można operować na obiektach danej klasy. W C# każda klasa dziedziczy po klasie Object i może dziedziczyć tylko po jednej klasie. Nie ma natomiast ograniczeń, jeżeli chodzi o dziedziczenie po interfejsach.

Podstawowa deklaracja klasy

Poniżej zamieszczam ogólny wzór podstawowej deklaracji klasy:

Listing 1
  1. rodzaj_dostępu class nazwa_klasy : nazwa_klasy_bazowej, interfejs1, interfejs2, ...
  2. {
  3. rodzaj_dostępu typ_danych pole1;
  4. rodzaj_dostępu typ_danych pole2;
  5. rodzaj_dostępu nazwa_klasy(typ_danych pole1, typ_danych pole2) // konstruktor
  6. : base() // wywołanie konstruktora klasy bazowej
  7. {
  8. this.pole1 = pole1;
  9. this.pole2 = pole2;
  10. }
  11. rodzaj_dostępu nazwa_klasy(nazwa_klasy obiekt_klasy) // konstruktor kopiujący
  12. : base(obiekt_klasy) // wywołanie konstruktora kopiującego klasy bazowej
  13. {
  14. this.pole1 = obiekt_klasy.pole1;
  15. this.pole2 = obiekt_klasy.pole2;
  16. }
  17. rodzaj_dostępu ~nazwa_klasy() //destruktor
  18. {
  19. }
  20. }

Oczywiście rodzaj dostępu może być jednym z pięciu dostępnych:

  • public - oznacza, że dana zmienna lub metoda są dostępne z każdego miejsca kodu. Ten typ dostępu jest domyślny dla interfejsów;
  • private - oznacza, że dana zmienna lub metoda są dostępne tylko z wnętrza danego typu, w którym została zadeklarowana. Ten typ dostępu jest domyślny dla klas i struktur;
  • protected - oznacza, że dana zmienna lub metoda są dostępne z wnętrza klasy do której należy oraz z wnętrza klas pochodnych;
  • internal - oznacza, że dana zmienna lub metoda są dostępne jedynie z wnętrza złożenia. C# kompiluje pliki *.cs w moduły a następnie grupuje w złożenia;
  • protected internal - oznacza, że dana zmienna lub metoda są dostępne z wnętrza klasy, w której została zadeklarowana lub z wnętrza złożenia.

Dodawanie pliku klasy do projektu

W głównym kodzie programu (czyli w pliku Program.cs) można co prawda umieszczać deklaracje klas, jednakże nie jest to zalecane zwłaszcza w przypadku dużych projektów. Z tego też powodu warto nauczyć się tworzyć dodatkowe pliki z kodem klas. W tym celu należy wcisnąć kombinację klawiszy Ctr+Alt+L lub w menu kliknąć View→Source Explorer, powinno pojawić się okno Source Explorer, w którym niezwłocznie należy kliknąć prawym przyciskiem myszy by w menu podręcznym kliknąć pozycję Add→Class....

Rys. 1
Menu kontekstowe programu VS EE dostępne z poziomu okna Source Explorer

Po kliknięciu wcześniej wymienionej pozycji menu pojawić się powinno okno dialogowe Add New Item - Klasy, w którym niezwłocznie wpisać należy nazwę klasy dodawanej, czyli Point2D po czym należy wcisnąć przycisk Add by plik został dodany.

Rys. 2
Okno dialogowe Add New Item - Klasy, umożliwiające dodawanie nowego pliku z klasą.

Przykład implementacji klas

W nowo utworzonym pliku zamieszczony zostanie następujący kod dwóch klas: Point2D i Point3D:

Listing 2
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace Klasy
  6. {
  7. // ########################### DEKLARACJA KLASY POINT@D #############################
  8. public class Point2D
  9. {
  10. // ####################### CHRONIONE POLA KLASY #################################
  11. protected double x;
  12. protected double y;
  13. // ####################### KONSTRUKTORY KLASY ###################################
  14. public Point2D() // konstruktor zerujący
  15. {
  16. x = y = 0;
  17. }
  18. public Point2D(double x, double y) // konstruktor ustawiajacy
  19. {
  20. this.x = x;
  21. this.y = y;
  22. }
  23. public Point2D(Point2D p) // kosntruktor kopiujący
  24. {
  25. this.x = p.x;
  26. this.y = p.y;
  27. }
  28. // ######## WŁAŚCIWOŚCI KLASY ##########
  29. public double Y
  30. {
  31. get { return y; }
  32. set { y = value; }
  33. }
  34. public double X
  35. {
  36. get { return x; }
  37. set { x = value; }
  38. }
  39. public double Length
  40. {
  41. get { return Math.Sqrt(x * x + y * y); } // pobieranie długości wektora
  42. set // ustawianie długości wektora
  43. {
  44. if (x != 0 || y != 0) // gdy wektor nie jest zerowy to
  45. {
  46. double k = value / Length;
  47. x *= k; // skalowanie składowej x wektora
  48. y *= k; // skalowanie składowej y wektora
  49. }
  50. }
  51. }
  52. // ########### METODY #############
  53. public override string ToString() // przeładowana metoda ToString klasy bazowej Object
  54. {
  55. return "Point2D x = " + x + "; y = " + y;
  56. }
  57. }
  58. // ############################## DEKLARACJA KLASY POINT3D #################################
  59. public class Point3D : Point2D // dziedziczy po Point2D
  60. {
  61. // ########################## CHRONIONE POLA KLASY #####################################
  62. protected double z;
  63. // ########################## KONSTRUKTORY KLASY #######################################
  64. public Point3D()
  65. : base() // wywołanie bezparametrowego kosntruktora klasy bazowej
  66. {
  67. z = 0;
  68. }
  69. public Point3D(double x, double y, double z)
  70. : base(x, y) // wywołanie ustawiającego konstruktora klasy bazowej
  71. {
  72. this.z = z;
  73. }
  74. public Point3D(Point3D p) // konstruktor kopiujący
  75. : base(p) // wywołanie kontruktora kopiującego klasy bazowej
  76. {
  77. z = p.z;
  78. }
  79. // ################# WŁAŚCIWOŚCI ###############
  80. public double Z
  81. {
  82. get { return z; }
  83. set { z = value; }
  84. }
  85. public new double Length // przysłanianie właściwości z klasy bazowej (oznacza to słowo kluczowe new)
  86. {
  87. get { return Math.Sqrt(x * x + y * y + z * z); } // pobieranie długości wektora
  88. set // ustawianie długości wektora
  89. {
  90. if (x != 0 || y != 0 || z != 0)
  91. {
  92. double k = value / Length;
  93. X *= k;
  94. Y *= k;
  95. z *= k;
  96. }
  97. }
  98. }
  99. // ################# METODY ################
  100. public new string ToString() // przysłanianie metody z klasy bazowej (oznacza to słowo kluczowe new)
  101. {
  102. return "Point3D x = " + X + "; y = " + Y + "; z = " + z;
  103. }
  104. }
  105. }

O właściwościach rozpisywałem się przy okazji omawiania tematu związanego z Programowanie → Podstawy C# → Struktury, również temat dotyczący metod został już niejako poruszony, natomiast to na co należy zwrócić uwagę, to sposób dziedziczenia i obsługi konstruktorów klasy.

W pliku Program.cs należy umieścić następujący kod:

Listing 3
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace Klasy
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. var p3d = new Point3D(10, 20, 30);
  12. Console.WriteLine(p3d.ToString());
  13. Point2D p2d = p3d;
  14. Console.WriteLine(p2d.ToString());
  15. Console.ReadLine();
  16. }
  17. }
  18. }

Skompilowanie kodu da następujący efekt:

Point3D x = 10; y = 20; z = 30
Point2D x = 10; y = 20

Stało się tak, ponieważ klasa Point3D dziedziczy po klasie Point2D.

Komentarze