Jedna z tych klas, implementująca interfejs w postaci listy, przedstawiona została na listingu 3.70. Listing 3.70. Implementacja interfejsu IContainer // uses Borland.Vcl.Classes type TListContainer = class(TStringList, IContainer) procedure IContainer.AddElement = Append; procedure DeleteElement(const ElementName: string); 340 Delphi 2005 function GetElementCount: integer; function GetFirstElementName: string; end; implementation procedure TListContainer.DeleteElement(const ElementName: string); begin if IndexOf(ElementName)>-1 then Delete(IndexOf(ElementName)); end; function TListContainer.GetElementCount: integer; begin Result := Count; end; function TListContainer.GetFirstElementName: string; begin if Count>0 then Result:=Strings[0] else Result := '(Lista jest pusta)'; if Result='' then Result := '(Pierwszy element nie ma nazwy.)'; end; Klasa TListContainer dziedziczy pełną funkcjonalność listy z klasy TStringList pochodzącej z biblioteki VCL.NET, i na przykład udostępnia wykorzystywane na listingu metody Append, Delete, IndexOf, Count i Strings. Jak widać, klasa TListContainer wła- ściwie przenosi działanie funkcji klasy TStringList do metod wymienianych w interfejsie IContainer. Zmiany nazw metod W przypadku metody IContainer.AddElement operacje wykonywane w implementacji interfejsu są wyjątkowo proste, ponieważ działanie odziedziczonej metody Append jest całkowicie zgodne z tym, co powinna robić metoda AddElement, a na dodatek ma ona dokładnie taki sam format wywołania (jeden parametr typu String i brak wartości zwracanej). Właśnie dlatego w interfejsie IContainer nie ma potrzeby implementowania metody AddElement, ale wystarczy połączyć ją z istniejącą metodą TStringList.Append: procedure IContainer.AddElement = Append; Takie jawne powiązanie metody interfejsu z metodą implementacji możliwe jest również wtedy, gdy tworzymy własną metodę implementacji i nadajemy jest nazwę zupełnie inną od nazwy metody interfejsu. W takiej sytuacji trzeba tylko pamiętać o uzupełnieniu nazwy metody interfejsu o odpowiednią klauzulę zmiany nazwy. Funkcje pomocy w programowaniu i uzupełnianie klas Dostępne w edytorze Delphi funkcje pomocy w programowaniu, w zakresie implementowania interfejsów oferują jeszcze jedną ciekawą rzecz: Jeżeli kursor edytora znajduje się wewnątrz deklaracji klasy, która obsługuje interfejsy, to po naciśnięciu w pustym wierszu klawiszy Ctrl+Spacja wyświetlona zostanie lista brakujących jeszcze Rozdział 3. ♦ Język Delphi w środowisku .NET 341 implementacji metod interfejsów. Normalnie lista wyboru wyświetlana wewnątrz deklaracji klasy zawiera tylko metody odziedziczone z klasy bazowej, które można pokryć w klasie wywiedzionej. Jeżeli jednak w klasie tej brakuje jeszcze metod wymaganych przez implementowany interfejs, to Delphi wyświetla je na samym początku wyświe-tlanej listy, a dodatkowo wyróżnia kolorem czerwonym. Oczywiście można też wywołać funkcję uzupełniania klasy (naciskając kombinację klawiszy Shift+Ctrl+C), żeby w ten sposób przygotować szkielety implementacji wszystkich metod wymienionych w deklaracji tej klasy. Druga implementacja interfejsu IContainer Druga klasa z przykładowego programu, implementująca interfejs IContainer, to klasa samego formularza aplikacji — jak już wspominałem, jest to aplikacja korzystająca z biblioteki VCL.NET, dlatego formularz ten nie jest wywiedziony z klasy System. Windows.Forms.Form, ale z klasy TForm: type TForm1 = class(TForm, IContainer) Możemy sobie tu podarować ponowne wypisywanie wszystkich metod interfejsu IContainer. Podobnie niewiele do omawianego tematu wnoszą nam implementacje metod tego interfejsu. W ramach przykładu przedstawię zatem (na listingu 3.71) wy- łącznie implementację metody AddElement, która dynamicznie tworzy obiekty typu TButton pochodzącego z biblioteki VCL.NET i dodaje go do obszaru na formularzu (kontrolka typu TScrollBox) przeznaczonego na tworzone w ten sposób przyciski. Listing 3.71. Implementacja metody AddElement w drugiej klasie implementującej interfejs IContainer procedure TForm1.AddElement(const ElementName: string); var B: TButton; const AddCount: Integer = 0; begin B := TButton.Create(self); B.Parent := ScrollBox1; B.Width := 100; B.Top := (AddCount div 5)*B.Height; B.Left := (AddCount mod 5)*B.Width; B.Caption := ElementName; inc(AddCount); end; procedure TForm1.DeleteElement(const ElementName: string); var i: Integer; begin for i := ScrollBox1.ControlCount-1 downto 0 do if (ScrollBox1.Controls[i] as TButton).Caption = ElementName then ScrollBox1.Controls[i].Free; end; 342 Delphi 2005 Tworzenie obiektów z interfejsami
|