Provided by: libmoops-perl_0.034-1_all bug

NAME

       Moops::Manual::Objects101 - an introduction to object oriented programming using Moops

SYNOPSIS

       This tutorial assumes some knowledge of procedural programming in Perl, and provides a
       gentle introduction to the object oriented programming paradigm.

DESCRIPTION

       Object oriented programming is a programming paradigm based around programming classes,
       and manipulating instances of those classes called objects. These can be objects that
       appear on the screen (e.g., pictures, textboxes, etc.) or are part of the programming
       (e.g.  actors, connections, particles, etc.).

   Classes
       Structures are very similar to classes in that they collect data together. However,
       classes extend this idea and are made from two different things:

       Attributes
           Things that the object stores data in, similar to variables.

       Methods
           Functions and Procedures attached to an Object and allowing the object to perform
           actions.

       Let's take a look at the following example:

          use Moops;

          class Car
          {
             lexical_has max_speed => (
                is       => 'rw',
                accessor => \(my $max_speed),
                isa      => Int,
                default  => 90,
             );

             has fuel => (
                is       => 'rw',
                isa      => Int,
             );

             has speed => (
                is       => 'rw',
                isa      => Int,
                trigger  => method ($new, $old?) {
                   confess "Cannot travel at a speed of $new; too fast"
                      if $new > $self->$max_speed;
                },
             );

             method refuel (Int $x) {
                say "Pumping gas!";
                $self->fuel( $self->fuel + $x );
             }

             method drive () {
                $self->fuel( $self->fuel - 1 );
             }
          }

       You can see that the class is called Car and it has:

       •   Three attributes: $max_speed (which is a lexical/private attribute), "fuel", and
           "speed";

       •   Two methods: "refuel" and "drive".

       Remember this is a class and therefore only a template, we need to "create" it using an
       object.

       Attributes

       These store information about the object. In the example above we store the "fuel",
       "speed", and $max_speed. The attributes are attached to the class, and if there are
       several instances (objects) of the class then each will store its own version of these
       variables.

       Unlike many other programming languages, Perl has no native concept of attributes. The
       "has" keyword instead sets up some extra methods for your class, called "accessors", which
       allow you to access the data for the attributes.

       $max_speed has a lexical accessor, stored in a lexical ("my") variable, so cannot be
       directly accessed outside the scope where it was declared.

       Methods

       Unlike structures, OOP allows you to attach functions and procedures to your code. This
       means that not only can you store details about you car (the attributes), you can also
       allow for subroutines such as "drive" and "refuel", which are attached to each class.

   OO - PIIE
       When talking about OOP you must remember OO-PIIE (yummy pie!)

       OO  Object Orientation

       PIIE
           Polymorphism, Inheritance, Instantiation, and Encapsulation

       Instantiation

       As we have seen a class is a template for something; you can't actually execute a class;
       you must instantiate it: that is create an instance of an class in the form of an object.

          my $polo = Car->new;
          my $escort = Car->new;

       The code above creates objects called $polo and $escort, both of class type Car (which we
       declared earlier). We can now use all the public attributes and methods:

          $polo->refuel(100);    # assuming fuel starts at 0
          $polo->drive();
          $polo->drive();

          $escort->refuel(50);   # assuming fuel starts at 0

          for my $x (1 .. 20) {
             $escort->drive();
             $polo->drive();
          }

          $polo->refuel(10);

          say "polo: ", $polo->fuel;
          say "escort: ", $escort->fuel;

       This would output the following:

          Pumping gas!
          Pumping gas!
          Pumping gas!
          polo: 88
          escort: 30

       Encapsulation

       You noticed that we used "lexical_has" to declare "max_speed" instead of "has". What this
       means is that these attributes are not directly accessible from outside the definition of
       the class. Let's take our polo class as an example:

          $polo->fuel(100);   # this directly alters the fuel level of $polo

       In the example we access the "fuel" attribute of the polo class and give the car 100 units
       of fuel. Because "fuel" is declared as public, there are no restrictions in accessing it.

       However, when we try the following we run into trouble:

          $polo->$max_speed(100);

       The reason that this wouldn't work is because we have declared the $max_speed attribute
       lexically. If something is declared lexically you can't access it externally, but how do
       you access it? The only way to access a lexical (private) attribute is to use a public
       method.

       In the Car code example we could have:

          method get_top_speed () {
             return $self->$max_speed;
          }

       Because this method is public we can call it from outside the class. And because
       "get_top_speed" is declared inside the Car class, it can have access to all the private
       attributes and methods.

       Inheritance

       Building on the car example above, what would happen if we wanted to declare an electric
       car? Well we'd probably want to store some information on the number of batteries that it
       has:

          use Moops imports => ['Lexical::Accessor'];

          class ElectricCar
          {
             lexical_has max_speed => (
                is       => 'rw',
                accessor => \(my $max_speed),
                isa      => Int,
                default  => 90,
             );

             has num_batteries => (
                is       => 'rw',
                isa      => Int,
                default  => 8,
             );

             has fuel => (
                is       => 'rw',
                isa      => Int,
             );

             has speed => (
                is       => 'rw',
                isa      => Int,
                trigger  => method ($new, $old?) {
                   confess "Cannot travel at a speed of $new; too fast"
                      if $new > $self->$max_speed;
                },
             );

             method refuel (Int $x) {
                # HOLD ON!
             }
          }

       This seems like a very long and tedious task rewriting all the same code again. You're
       right! It would be far better if we only had to declare all the new stuff we wanted to
       add. OOP allows for inheritance, where a new class can inherit the attributes and methods
       of a parent class:

          class ElectricCar extends Car {
             has num_batteries => (
                is       => 'ro',
                isa      => Int,
                default  => 8,
             );
          }

       This means that everything that "Car" declared is now accessible from "ElectricCar", as
       well as the new "num_batteries" attribute. Let's instantiate this example and see what's
       possible:

          my $gwiz = ElectricCar->new(num_batteries => 6, fuel => 100);
          say $gwiz->num_batteries;    # defined in ElectricCar
          say $gwiz->fuel;             # defined in Car

       Using inheritance makes creating new classes very quick and easy. It also allows for a
       modular approach to creating classes, where you might never use the base class at all, but
       only as a means of creating other child classes.

       Rather than having to rewrite the same functionality for similar objects, OOP allows you
       to reuse attributes and methods from parent classes.

       Polymorphism

       When you were young you might have watched the Mighty Morphin' Power Rangers. These guys
       could morph from regular people into their power suits. Sadly polymorphism isn't that
       exciting, but it does allow you to change the function of attributes and methods when you
       are inheriting from a parent class. Consider our car example again. When we created the
       "ElectricCar" object we inherited from "Car" and added the "num_batteries" attribute and
       methods. But what happens when we try and refuel, let's take a look at the code:

          method refuel (Int $x) {
             say "Pumping gas!";
             $self->fuel( $self->fuel + $x );
          }

       Well this just won't do! We are creating an electric car and we don't want to say that we
       are pumping gas; what would our sandal-socked yoghurt eating friends say?! So for the
       "ElectricCar" class, we want to inherit everything from "Car", but we want to
       morph(change) the "refuel" method. To do that we override the method inherited from the
       superclass:

          class ElectricCar extends Car {
             has num_batteries => (
                is       => 'ro',
                isa      => Int,
                default  => 8,
             );
             override refuel (Int $x) is override {
                say "Pure renewable energy!";
                $self->fuel( $self->fuel + $x );
             }
          }

BUGS

       Please report any other bugs to <http://rt.cpan.org/Dist/Display.html?Queue=Moops>.

SEE ALSO

       Moops.

AUTHOR

       Toby Inkster <tobyink@cpan.org>, plus the authors credited at:
       <http://en.wikibooks.org/w/index.php?title=A-level_Computing/AQA/Problem_Solving,_Programming,_Operating_Systems,_Databases_and_Networking/Programming_Concepts/Object-oriented_programming_(OOP)&action=history>
       (as of 15 December 2013).

COPYRIGHT AND LICENCE

       Copyright 2013-2014 Toby Inkster and others.

       Text is available under the Creative Commons Attribution/Share-Alike License.

       <http://creativecommons.org/licenses/by-sa/3.0/>.

DISCLAIMER OF WARRANTIES

       THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
       WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
       PURPOSE.