示例:外部迭代器 说明: 我们将给出两个迭代器的实现, 一个以从前到后的次序遍历该表列, 而另一个以从后到前的次序遍历,然后我们说明如何使用这些迭代器。 代码: 列表接口uList unit uList; interface uses Contnrs; type TList1 = class(TObjectList) private function GetCount: integer; function GetItems(Index: integer): TObject; public property Count: integer read GetCount; property Items[Index: integer]: TObject read GetItems; default; end; implementation function TList1.GetCount: integer; begin Result := inherited Count; end; function TList1.GetItems(Index: integer): TObject; begin Result := inherited Items[Index]; end; end. 迭代器接口uIterator unit uIterator; interface uses sysutils; type TIterator = class public procedure First(); virtual; abstract; procedure Next(); virtual; abstract; function IsDone(): Boolean; virtual; abstract; function CurrentItem(): TObject; virtual; abstract; end; IteratorOutOfBounds = class(Exception) public constructor Create; end; implementation constructor IteratorOutOfBounds.Create; begin inherited Create('Iterator Out Of Bounds'); end; end. 迭代器uListIterator unit uListIterator; interface uses uIterator,uList; type TListIterator = class(TIterator) private FList: TList1; FCurrent: integer; public constructor Create(const AList: TList1); //--- procedure First(); override; procedure Next(); override; function IsDone(): Boolean; override; function CurrentItem(): TObject; override; end; implementation constructor TListIterator.Create(const AList: TList1); begin FList := AList; FCurrent := 0; end; procedure TListIterator.First; begin FCurrent := 0; end; procedure TListIterator.Next; begin FCurrent := FCurrent + 1; end; function TListIterator.IsDone: Boolean; begin Result := FCurrent >= FList.Count; end; function TListIterator.CurrentItem: TObject; begin if self.IsDone then raise IteratorOutOfBounds.Create; //--- Result := FList.Items[FCurrent]; end; end. 迭代器uReverseListIterator unit uReverseListIterator; interface uses uIterator,uList; type TReverseListIterator = class(TIterator) private FList: TList1; FCurrent: integer; public constructor Create(const AList: TList1); //--- procedure First(); override; procedure Next(); override; function IsDone(): Boolean; override; function CurrentItem(): TObject; override; end; implementation constructor TReverseListIterator.Create(const AList: TList1); begin FList := AList; FCurrent := 0; end; procedure TReverseListIterator.First; begin FCurrent := FList.Count - 1; end; procedure TReverseListIterator.Next; begin FCurrent := FCurrent - 1; end; function TReverseListIterator.IsDone: Boolean; begin Result := FCurrent < 0; end; function TReverseListIterator.CurrentItem: TObject; begin if self.IsDone then raise IteratorOutOfBounds.Create; //--- Result := FList.Items[FCurrent]; end; end. 雇员uEmployee unit uEmployee; interface uses StdCtrls,uIterator; type TEmployee = class private FName: string; FMemo: TMemo; public constructor Create(const AName: string; AMemo: TMemo); //--- procedure Print(); //--- property Name: string read FName; end; procedure PrintEmployees(I:TIterator); implementation procedure PrintEmployees(I:TIterator); begin I.First; while not I.IsDone do begin TEmployee(I.CurrentItem).Print; I.Next; end; end; constructor TEmployee.Create(const AName: string; AMemo: TMemo); begin FName := AName; FMemo := AMemo; end; procedure TEmployee.Print; begin FMemo.Lines.Add(FName); end; end. 迭代器使用 procedure TForm1.Button1Click(Sender: TObject); var AEmployees: TList1; AForward: TListIterator; ABackward: TReverseListIterator; begin self.Memo1.Clear; //--- AEmployees := TList1.Create; try with AEmployees do begin Add(TEmployee.Create('111',self.Memo1)); Add(TEmployee.Create('222',self.Memo1)); Add(TEmployee.Create('333',self.Memo1)); end; //--- AForward := TListIterator.Create(AEmployees); ABackward := TReverseListIterator.Create(AEmployees); try PrintEmployees(AForward); PrintEmployees(ABackward); finally AForward.Free; ABackward.Free; end; finally AEmployees.Free; end; end;
