Zrozumienie pomocników klasy (i nagrywania) Delphi

Funkcja języka Delphi dodana kilka lat temu (dawno temu w Delphi 2005) o nazwie „Pomocnicy klas” ma na celu dodanie nowych funkcji do istniejącej klasy (lub rekordu) poprzez wprowadzenie nowych metod do klasy (rekordu).

Poniżej znajdziesz więcej pomysłów na pomocników klasowych + dowiedz się, kiedy i kiedy nie korzystać z pomocników klasowych.

Pomocnik klasy dla...

Krótko mówiąc, pomocnik klasy jest konstrukcją, która rozszerza klasę, wprowadzając nowe metody w klasie pomocnika. Pomocnik klasy pozwala rozszerzyć istniejącą klasę bez jej modyfikacji lub dziedziczenia.

Aby rozszerzyć klasę TStrings VCL, należy zadeklarować i zaimplementować pomocnika klasy, jak poniżej:

rodzaj
TStringsHelper = pomocnik klasy dla TStrings. publicznyfunkcjonować Zawiera (const aString: string): boolean; koniec; 

Powyższa klasa, zwana „TStringsHelper”, jest pomocnikiem klasy dla typu TStrings. Zauważ, że TStrings jest zdefiniowany w Classes.pas, jednostce domyślnie dostępnej w klauzuli use dla dowolnej Delfy na przykład jednostka formularza.

instagram viewer

Funkcja, którą dodajemy do typu TStrings za pomocą naszego pomocnika klasy, to „Zawiera”. Implementacja może wyglądać następująco:

funkcjonować TStringsHelper. Zawiera (const aString: string): boolean; zaczynać
wynik: = -1 <> IndexOf (aString); koniec; 

Jestem pewien, że używałeś powyższego wiele razy w swoim kodzie - aby sprawdzić, czy jakiś potomek TStrings, jak TStringList, ma jakąś wartość ciągu w swojej kolekcji Items.

Zwróć uwagę, że na przykład właściwość Items TComboBox lub TListBox jest typu TStrings.

Po zaimplementowaniu TStringsHelper i pola listy w formularzu (o nazwie „ListBox1”) możesz teraz sprawdzić, czy jakiś ciąg znaków jest częścią właściwości Items pola listy, używając:

gdyby ListBox1.Items. Zawiera („jakiś ciąg”) następnie... 

Class Helpers Go and NoGo

Wdrożenie pomocników klas ma pewne pozytywne i pewne (możesz pomyśleć) negatywne skutki dla twojego kodowania.

Zasadniczo powinieneś unikać rozszerzania własnych klas - tak jakbyś musiał dodać nowe funkcje własne klasy niestandardowe - dodaj nowe elementy bezpośrednio do implementacji klasy - nie używając klasy pomocnik.

Pomocnicy klas są więc bardziej zaprojektowani, aby rozszerzyć klasę, gdy nie można (lub nie trzeba) polegać na normalnym dziedziczeniu klas i implementacjach interfejsu.

Pomocnik klasy nie może deklarować danych instancji, takich jak nowe pola prywatne (lub właściwości, które odczytują / zapisują takie pola). Dodawanie nowych pól klas jest dozwolone.

Pomocnik klasy może dodawać nowe metody (funkcja, procedura).

Przed Delphi XE3 można było rozszerzać tylko klasy i rekordy - typy złożone. Od wersji Delphi XE 3 możesz także rozszerzyć proste typy, takie jak liczba całkowita lub łańcuch znaków lub TDateTime, i mieć konstrukcję:

var
s: string; zaczynać
s: = 'Pomocnicy Delphi XE3'; s: = s. Duże litery. Rewers; koniec; 

W najbliższej przyszłości napiszę o prostym typie pomocnika Delphi XE 3.

Gdzie jest MY Class Helper

Jednym z ograniczeń korzystania z pomocników klasowych, które może pomóc ci „zastrzelić się w nogę”, jest fakt, że możesz zdefiniować i powiązać wielu pomocników z jednym typem. Jednak tylko zero lub jeden pomocnik ma zastosowanie w dowolnej określonej lokalizacji w kodzie źródłowym. Obowiązuje pomocnik zdefiniowany w najbliższym zakresie. Zakres pomocnika klasy lub rekordu określa się normalnie Delfy moda (na przykład od prawej do lewej w klauzuli użycia jednostki).

Oznacza to, że możesz zdefiniować dwa pomocniki klasy TStringsHelper w dwóch różnych jednostkach, ale tylko jedna będzie obowiązywać, gdy zostanie faktycznie użyta!

Jeśli pomocnik klasy nie jest zdefiniowany w jednostce, w której używasz wprowadzonych metod - co w większości przypadków tak będzie, nie wiesz, jakiej implementacji pomocnika klasy faktycznie byś używał. Dwie klasy pomocników dla TStrings, o różnych nazwach lub znajdujących się w różnych jednostkach, mogą mieć różną implementację dla metody „Contains” w powyższym przykładzie.

Używać czy nie?

Tak, ale pamiętaj o możliwych skutkach ubocznych.

Oto kolejne przydatne rozszerzenie wyżej wspomnianego pomocnika klasy TStringsHelper


TStringsHelper = pomocnik klasy dla TStrings. prywatnyfunkcjonować GetTheObject (const ciąg: strunowy): TObject; procedura SetTheObject (const ciąg: strunowy; const Wartość: TObject); publicznywłasność ObjectFor [const ciąg: strunowy]: TObject czytać GetTheObject pisać SetTheObject; koniec;... funkcjonować TStringsHelper. GetTheObject (const ciąg: strunowy): TObject; var
idx: liczba całkowita; zaczynać
wynik: = zero; idx: = IndexOf (aString); gdyby idx> -1 następnie wynik: = Obiekty [idx]; koniec; procedura TStringsHelper. SetTheObject (const ciąg: strunowy; const Wartość: TObject); var
idx: liczba całkowita; zaczynać
idx: = IndexOf (aString); gdyby idx> -1 następnie Obiekty [idx]: = wartość; koniec; 

Jeśli byłeś dodawanie obiektów do listy ciągów, możesz zgadnąć, kiedy użyć powyższej przydatnej właściwości pomocnika.