unit Unit2; interface type // Car = Carriage TCarriage = class // суперкласс любого вагона private fNextCar: TCarriage; protected fCarType: string; // каждый наследник меняет эту стороку public constructor Create; virtual; destructor Destroy; override; procedure HitchCarriage(Car: TCarriage); //прицепить вагон function CountCars: integer; property NextCar: TCarriage read fNextCar; // сслка на следующий вагон property CarType: string read fCarType; // тип вагона end;//of class TPassengerCar = class(TCarriage) // суперкласс любого пассажирского вагона private fSeatsCount: integer; fSeatCost: real; public constructor Create; override; property SeatsCount: integer read fSeatsCount write fSeatsCount; //кол-во мест property SeatCost: real read fSeatCost write fSeatCost; //стоимость места в вагоне end;//of class TDormitoryCar = class(TPassengerCar) // купе private fBedCost: real; public constructor Create; overload; override; constructor Create(ASeatsCount: integer; ASeatCost, ABedCost: real); overload; virtual; //добавим свойство стоимости белья property BedCost: real read fBedCost write fBedCost; //стоимость послельного белья end;//of class TParlorCar = class(TPassengerCar) // общий вагон public constructor Create; override; constructor Create(ASeatsCount: integer; ASeatCost: real); overload; virtual; end;//of class //эта процедура показывет, как можно создать состав function MakeTrain: TCarriage; //эта процедура показывает. как можно пройти по составу и прочитать инфу procedure EnumTrain(FirstCar: TCarriage); implementation { ### TCarriage ############################################################## } constructor TCarriage.Create; begin //почти пустой виртуальный конструктор //его переопределим в наследниках fCarType:='UnknownCar'; end; destructor TCarriage.Destroy; begin //при уничтожении вагона уничтожаются все вагоны, //которые к нему прицеплены if NextCar <> nil then NextCar.Destroy; end; procedure TCarriage.HitchCarriage(Car: TCarriage); begin //цепляем вагон if Car = nil then Exit; if fNextCar <> nil then Car.fNextCar:=fNextCar; fNextCar:=Car; end; function TCarriage.CountCars: integer; var Nxt: TCarriage; begin //считаем, сколько вагонов к нам прицеплено Result:=0; Nxt:=NextCar; while Nxt <> nil do begin inc(Result); Nxt:=Nxt.NextCar end; end; { ### TPassengerCar ########################################################## } constructor TPassengerCar.Create; begin fCarType:='Passenger'; end; { ### TDormitoryCar ########################################################## } constructor TDormitoryCar.Create; begin inherited; fCarType:='Dormitory'; // ставим все параметры по умолчанию fSeatCount:=40; fSeatCost:=150.0; fBedCost:=1.0; end; constructor TDormitoryCar.Create(ASeatsCount: integer; ASeatCost, ABedCost: real); begin Create; // ставим введённые параметры fSeatCount:=ASeatsCount; fSeatCost:=ASeatCost; fBedCost:=ABedCost; end; { ### TParlorCar ############################################################# } constructor TParlorCar.Create; begin inherited; fCarType:='Parlor'; // ставим все свойства по умолчанию fSeatCount:=150; fSeatCost:=50.0; end; constructor TParlorCar.Create(ASeatsCount: integer; ASeatCost: real); begin Create; // ставим введённые параметры fSeatCount:=ASeatsCount; fSeatCost:=ASeatCost; end; { ############################################################################ } function MakeTrain: TCarriage; var LastCar: TCarriage; begin LastCar:=TParlorCar.Create(200, 1.5); //создаём общий вагон Result:=LastCar; LastCar.HitchCarriage(TDormitoryCar.Create); //присоединяем купйный вагон LastCar:=LastCar.NextCar; LastCar.HitchCarriage(TParlorCar.Create); //присоединяем ещё один общий вагон LastCar:=LastCar.NextCar; LastCar.HitchCarriage(TDormitoryCar.Create(25, 14.3, 2.5); //ну, и ещё одно купе end; procedure EnumTrain(FirstCar: TCarriage); var ThisCar: TCarriage; begin ThisCar:=FirstCar; while ThisCar <> nil do begin if ThisCar.CarType = 'Dormitory' then begin //вагон - купе end else if ThisCar.CarType = 'Parlor' then begin //вагон - общий end else begin //напонятный тип вагона - ошибка end; ThisCar:=ThisCar.NextCar; end; end; end.