-- Chapter 23 - Program 3 with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO; use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO; package Conveyance5 is -- Begin with a basic transportation type. type TRANSPORT is tagged private; procedure Set_Values(Vehicle_In : in out TRANSPORT; Wheels_In : INTEGER); function Get_Wheels(Vehicle_In : TRANSPORT) return INTEGER; procedure Describe(Vehicle_In : TRANSPORT); -- Extend the basic type to a CAR type. type CAR is new TRANSPORT with private; procedure Set_Values(Vehicle_In : in out CAR; Passenger_Count_In : INTEGER); function Get_Passenger_Count(Vehicle_In : CAR) return INTEGER; procedure Describe(Vehicle_In : CAR); -- Extend the basic type to a TRUCK type. type TRUCK is new TRANSPORT with private; procedure Set_Values(Vehicle_In : in out TRUCK; Wheels_In : INTEGER; Passenger_Count_In : INTEGER); function Get_Passenger_Count(Vehicle_In : TRUCK) return INTEGER; procedure Describe(Vehicle_In : TRUCK); -- Extend the basic type to the BICYCLE type. type BICYCLE is new TRANSPORT with private; procedure Describe(Vehicle_In : BICYCLE); -- Print_Values is a class-wide operation. It can accept objects -- of any type within the TRANSPORT heirarchy. procedure Print_Values(Any_Vehicle : TRANSPORT'Class); private type TRANSPORT is tagged record Wheels : INTEGER; end record; type CAR is new TRANSPORT with record Passenger_Count : INTEGER; end record; type TRUCK is new TRANSPORT with record Passenger_Count : INTEGER; end record; type BICYCLE is new TRANSPORT with null record; end Conveyance5; package body Conveyance5 is -- Subprograms for the TRANSPORT record procedure Set_Values(Vehicle_In : in out TRANSPORT; Wheels_In : INTEGER) is begin Vehicle_In.Wheels := Wheels_In; end Set_Values; function Get_Wheels(Vehicle_In : TRANSPORT) return INTEGER is begin return Vehicle_In.Wheels; end Get_Wheels; procedure Describe(Vehicle_In : TRANSPORT) is begin Put("We are in the TRANSPORT procedure."); new_Line; end Describe; -- Subprograms for the CAR record procedure Set_Values(Vehicle_In : in out CAR; Passenger_Count_In : INTEGER) is begin Vehicle_In.Passenger_Count := Passenger_Count_In; end Set_Values; function Get_Passenger_Count(Vehicle_In : CAR) return INTEGER is begin return Vehicle_In.Passenger_Count; end Get_Passenger_Count; procedure Describe(Vehicle_In : CAR) is begin Put("We are in the CAR procedure."); new_Line; end Describe; -- Subprograms for the TRUCK record procedure Set_Values(Vehicle_In : in out TRUCK; Wheels_In : INTEGER; Passenger_Count_In : INTEGER) is begin -- This is one way to set the values in the base class Vehicle_In.Wheels := Wheels_In; -- This is another way to set the values in the base class Set_Values(TRANSPORT(Vehicle_In), Wheels_In); -- This sets the values in this class Vehicle_In.Passenger_Count := Passenger_Count_In; end Set_Values; function Get_Passenger_Count(Vehicle_In : TRUCK) return INTEGER is begin return Vehicle_In.Passenger_Count; end Get_Passenger_Count; procedure Describe(Vehicle_In : TRUCK) is begin Put("We are in the TRUCK procedure."); new_Line; end Describe; -- Subprograms for the BICYCLE record procedure Describe(Vehicle_In : BICYCLE) is begin Put("We are in the BICYCLE procedure."); New_Line; end Describe; -- Print_Values is a class-wide operation. It can accept objects -- of any type within the TRANSPORT heirarchy. procedure Print_Values(Any_Vehicle : TRANSPORT'Class) is begin -- Describe(Any_Vehicle); Put("This vehicle has"); Put(Any_Vehicle.Wheels, 2); Put(" wheels."); New_Line; -- The following line of code will produce an error because TRANSPORT -- and BICYCLE do not contain this variable. -- Put(Any_Vehicle.Passenger_Count, 5); end Print_Values; end Conveyance5; -- Result of execution -- -- (This program cannot be executed alone.)