UNIT TestClass;

   INTERFACE {$classes+}

      TYPE
         Class1 = SUBCLASS OF NIL
                     Class1Id: Integer;
                     Class2Id, Class3Id: Integer;
                     FUNCTION Create(CrParam: Integer): Class1;
                     PROCEDURE Proc1;
                  END;

         Class2 = SUBCLASS OF Class1
                     Field1, Field2: Integer;
                     Field3: Integer;
                     FUNCTION Create: Class2;
                    {PROCEDURE Proc1;}         {override of class1 proc}
                     PROCEDURE Proc2;
                     PROCEDURE Proc3;
                     PROCEDURE Proc4;
                  END;

         Class3 = SUBCLASS OF Class2
                     FUNCTION Create: Class3;
                    {PROCEDURE Proc1;}         {override of class1 proc}
                    {PROCEDURE Proc3;}         {override of class2 proc}
                     PROCEDURE ProcA;
                     PROCEDURE ProcB;
                     PROCEDURE ProcC;
                  END;

         Class4 = SUBCLASS OF Class3
                     FUNCTION Create: Class4;
                    {PROCEDURE ProcA;}         {override of class3 proc}
                    {PROCEDURE Proc4;}         {override of class2 proc}
                     FUNCTION ProcX: Class3;
                     PROCEDURE ProcY;
                     PROCEDURE ProcZ;
                  END;

         Class5 = SUBCLASS OF Class2
                     FUNCTION Create: Class5; ABSTRACT;
                     PROCEDURE ProcV; ABSTRACT;
                     PROCEDURE ProcU;
                     PROCEDURE ProcW; DEFAULT;
                  END;

         Class6 = SUBCLASS OF Class5
                     FUNCTION Create: Class6;
                    {PROCEDURE ProcV;}         {override ov class2 abstract proc}
                  END;

         Class7 = Class6;

      VAR
         i, j, k, l: Integer;

   IMPLEMENTATION

     PROCEDURE GardenVariety;

        BEGIN
           i := 1;
           j := 2;
           k := 3;
           l := 4;
        END;

     METHODS OF Class1;

        FUNCTION Create{CrParam: Integer): Class1};
           BEGIN {Create}
           END; {Create}

        PROCEDURE Proc1;
           BEGIN {Proc1}
           END; {proc1}
     END;

     METHODS OF Class2

        FUNCTION Create{: Class2};
           BEGIN {Create}
           self := create;
           END; {Create}

        PROCEDURE {class2 override} Proc1;
           BEGIN {Proc1 override}
           END; {Proc1}

        PROCEDURE Proc2;
           BEGIN {Proc2}
           self.field1 := 1;
           self.class1id := 2;
           self.proc1;
           WITH self DO {$h-}
              BEGIN
              field1 := 1;
              class1id := 2;
              proc1;
              END;
           END; {Proc2}

        PROCEDURE Proc3;
           Var
              c1: class1;
              c2: class2;

           BEGIN {Proc3}
              Class1.Proc1;
              Class2.Proc1;
              Class2.Proc2;
              c1 := Class1.Create(1);
              c2 := Class2.Create;
              c2.proc2;
              c2.proc3;
              c1 := class1(c2);
              WITH class1(c2) do
                 class1id := 1;
           END; {Proc3}

        PROCEDURE Proc4;

           VAR
              c1: class1;
              c2: class2;

           BEGIN {Proc4}
              c1 := class1(c2);
           END; {Proc4}

        BEGIN
          i := 1;
          j := 2;
        END;

     METHODS OF Class3;

        FUNCTION Create{: Class3};
           BEGIN {Create}
           END; {Create}

        PROCEDURE {class3 override} Proc1;
           BEGIN {Proc1 override}
           END; {Proc1}

        PROCEDURE ProcA;
           BEGIN {ProcA}
           END; {ProcA}

        PROCEDURE ProcB;
           BEGIN {ProcB}
           END; {ProcB}

        PROCEDURE ProcC;
           BEGIN {ProcC}
           END; {ProcC}

        PROCEDURE {class3 override} Proc3;
           BEGIN {Proc3 override}
           END; {Proc3}

     END;

     METHODS OF Class4;

        FUNCTION Create{: Class4};
           BEGIN {Create}
           END; {Create}

        PROCEDURE {class3 override} ProcA;
           BEGIN {ProcA override}
           END; {ProcA}

        PROCEDURE {class2 override} Proc4;
           BEGIN {Proc4 override}
           END; {Proc4}

        FUNCTION ProcX{: Class3};
           BEGIN {ProcX}
           END; {ProcX}

        PROCEDURE ProcY;
           BEGIN {ProcY}
           END; {ProcY}

        PROCEDURE ProcZ;
           BEGIN {ProcZ}
           END; {ProcZ}

        BEGIN
        END;

    METHODS OF Class5;
        (*
        FUNCTION Create{: Class5};
           BEGIN {Create}
           END; {Create}
        *)
        PROCEDURE ProcU;
           BEGIN {ProcU}
           END; {ProcU}

        PROCEDURE ProcW;
           BEGIN {ProcW}
           END; {ProcW}
     END;

    METHODS OF Class6;

        FUNCTION Create{: Class6};
           BEGIN {Create}
           END; {Create}

        PROCEDURE ProcV;

           VAR c1: class1;

           BEGIN {ProcV}
              c1 := class1.create(10);
              class1.proc1;
              c1.proc1;
           END; {ProcV}
     END;
END.

