CONCEPT
        Inheritance

DESCRIPTION
        Have you noticed how many objects in the system have the same
        functionality in common? Let's look at rooms for instance, they
        all have the ability to host people and provide commands. It's
        not that every room is programmed with the same basic functions
        again and again, rather it will use a model room and then make
        some special changes to it. That doesn't work by copying the
        file.. Ouch! Don't replicate code! But by putting a tiny inherit
        declaration
        
                inherit "<model-class>";
                
        at the beginning of your new file. This must come before any local
        ariables or functions. Once inherited your class will behave just
        like the model class, because all the public methods are available
        to the outside world. Now it is in your hands to change such an
        inherited behaviour. You have the following tools to do so:

        * Access to variables

        It is one of the best design decisions in LPC that variables
        are not accessible from outside, but you can use inherited
        variables just as if they were your own. Modifiers apply however.

        * Method overloading

                int method_that_also_exists_in_the_model() {
                        <your new code>
                }

        You can simply rewrite a method that is also defined in the model
        class, and thus change how it behaves. Contrary to other languages
        in LPC method overloading only matches the name of the method, so
        even by changing the amount and type of parameters you will mask
        out the original version of the method. You can even apply other
        modifiers to it as the original.

        * Calling inherited methods

                int method_that_also_exists_in_the_model() {
                        <your new code>
                        return ::method_that_also_exists_in_the_model();
                }

        You can add to the behaviour of a method by redefining it,
        then calling it from within your new version. You can actually
        call inherited methods from anywhere in your code. The double
        colon tells the compiler you are looking for the inherited
        variant.

EXAMPLE

        Let's imagine very simple food in a file called "/the/food.c":

                // unless "modified" variables are accessible by inheritors
                int vitamins = 10;

                // please overload this function with your own description
                public short() { return "something edible"; }

                // let's do some standard action for food
                public consume() {
                        this_player() -> nourish(vitamins);
                        destruct(this_object());
                }

        And now someone else decides to do some italian cooking in a
        file called "/the/fusilli.c"

                inherit "/the/food";

                // we have our own variables.
                int gone_cold = 0;

                // and we simply redefine the short() function to replace it
                public short() {
                    // description changes depending on gone_cold
                    return "a "+( gone_cold ? "stinking" : "steaming" )
                            +" plate of fusilli";
                }

                // we have a new function to make food go cold
                private deteriorate() {
                    gone_cold = 1;
                    write("The fusilli have gone cold.\n");
                }

                // assume this gets called at creation
                private create() {
                    // we can access the variable we inherited from food.c
                    vitamins = 44;           // tomato has plenty of vitamins

                    // go cold in 5 minutes
                    call_out( #'deteriorate, 5 * 60 );
                }

                // we can overload the function even with new parameters
                public consume(how) {
                    // fetch the name of the person, or use "Someone"
                    string name = this_player() -> name() || "Someone";

                    if (!gone_cold) {
                        write("You enjoy a delicious plate of fusilli.\n");
                        say(name +" guzzles a plate of hot fusilli.\n");
                    }
                    else if (how == "quickly") {
                        write("You eat the fusilli so quickly you "
                              "hardly notice they have gone cold.\n");
                        say(name +" wolfs down a plate of cold fusilli.\n");
                    }
                    else {
                        write("You eye the plate and wonder if you "
                              "really feel like eating cold fusilli.\n");
                        return; // don't eat
                    }

                    // and here comes the most important part:
                    // we execute consume() from food.c, so we
                    // actually inherit its behaviour.
                    ::consume();
                }

ADVANCED USAGE

        * Doing multiple inheritance

        While the Java(TM) language has so-called interfaces as a kludge,
        LPC doesn't need them as it supports real multiple inheritance.
        A very powerful feature, it lets you combine the behaviour of
        several classes into a new one. Simply put several lines of
        inherit declarations underneath each other. If you have name
        collisions in the namespace of inherited methods, you will have
        to address them explicitely with a "the/file"::method(args) syntax.

        * Wildcarded multiple inheritance

        LDMUD 3.2.1@117 introduces an advanced voodoo syntax which allows
        you to call several methods in model classes at once, but for some
        technical reasons it cannot pass any arguments. This works by
        writing a glob type match ('*' and '?' wildcards) into the string
        in front of the double colon, as in "*"::create(). I wouldn't
        recommend you to use this, it's better to be clearly conscious of
        what you inherit and do. But if you're desperate, there you go.

ADVANCED EXAMPLE

          inherit "foo";
          inherit "bar";
          inherit "baz";
          inherit "ball";

          reset() {
                "ba?"::reset();
                // calls bar::reset() and baz::reset()

                "ba*"::reset();
                // calls bar::reset(), baz::reset() and ball::reset()

                "*"::reset();
                // calls every inherited reset() function.

                "ball"::rejoice("Listen to italectro today!");
                // only explicit filename of model class allows
                // passing arguments to the inherited method
          }

AUTHOR
        symlynX of PSYC and Nemesis, with a little help from Someone

SEE ALSO
        functions(LPC), initialisation(LPC), modifiers(LPC), pragma(LPC),
        overloading(C)
        function_exists(efun), functionlist(efun), inherit_list(efun),
        symbol_variable(efun), variable_exists(efun), variable_list(efun).
