CSC/ECE 517 Fall 2010/ch1 2c jp: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 3: Line 3:
All extension objects contain two parts: a list of pointers to their prototype objects, and a set of instructions unique to itself.  When a method invocation is sent to an extension object, the object first looks to see if the method is defined in its own set of instructions.  If the method is not found within the objects own code, it then looks for the method among the object's prototype methods, and so on.  This system of method invocation is called delegation.  Programming languages without delegation cannot implement prototype-based programming.[4]  The examples in this article will use the Ruby programming language.
All extension objects contain two parts: a list of pointers to their prototype objects, and a set of instructions unique to itself.  When a method invocation is sent to an extension object, the object first looks to see if the method is defined in its own set of instructions.  If the method is not found within the objects own code, it then looks for the method among the object's prototype methods, and so on.  This system of method invocation is called delegation.  Programming languages without delegation cannot implement prototype-based programming.[4]  The examples in this article will use the Ruby programming language.


First, we create a class called FairyTaleCharacter with one method defined to show the character's morality.  We assume all fairy tale characters are good people:
JavaScript, Self, Io, NewtonScript, Omega, Cecil, Lua, Object-Lisp, Examplars, Agora, ACT-I, Kevo, Moostrap, Obliq, Garnet [5]


  class FairyTaleCharacter
In Ruby, you can define an extension object's prototype by using the SimpleDelegator class.  In order to use the SimpleDelegator class you must include the delegate file.  In this example we create two instances of class Polygon:
    def morality
      puts "I'm a good person!"
    end
  end
 
Next we create two instances of class FairyTaleCharacter:
 
  pinocchio = FairyTaleCharacter.new
  peterPan = FairyTaleCharacter.new


We want to create a third fairy tale character, Captain Hook, but he is not a good person like we originally assumed.  Instead of modifying our original class we can alter only the instance for Captain Hook by using the extend method:
  require 'delegate'
 
   class Polygon
   captainHook = FairyTaleCharacter.new
    attr_reader :sides
  module Evil
     def initialize(sides)
     def morality
       @sides = sides
       puts "I'm evil!"
     end
     end
   end
   end
   captainHook.extend(Evil)
   quadrilateral = Polygon.new(4)
  triangle = Polygon.new(3)


Now, if we were to invoke the morality method for these two object we would get different output for each:
Next we create an extension object called rectangle using quadrilateral as our prototype.  As I said before, we use the SimpleDelegator class and pass the prototype as the constructor argument:


   peterPan.morality #=> "I'm a good person!"
   rectangle = SimpleDelegator.new(quadrilateral)
   captainHook.morality #=> "I'm evil!"
   puts rectangle.sides # => 4


Finally, we wish to create an object to represent the Wicked Witch of the West.  She is evil, and can also fly around on her broomstickTo implement the flying functionality we create the Flying module:
To add functionality in our inheritance hierarchy we use the extend methodThe extend method will add functionality to a particular instance of a class:


   module Flying
   module Area
    def fly
  def area(length, width)
      puts "I'm flying!"
     length * width
     end
   end
   end
  quadrilateral.extend(Area)
  puts rectangle.area(10, 20) # => 200


Instead of creating a new instance of FairyTaleCharacter for the Wicked Witch and extending it with both the Evil and Flying modules we can use the object representing Captain Hook as a prototype by cloning the object and assigning the clone to our Wicked Witch object:
According to the definition of delegation, if the method invoked is not part of the calling object then it attempts to find the method in the prototype object.  Since the area method is not a part of the rectangle object the program then looks for the method in the prototype, quadrilateral.
 
  wickedWitch = captainHook.clone()
 
Finally, we augment her instance with the Flying module:
 
  wickedWitch.extend(Flying)
 
We can now invoke the morality method and the fly method:
 
  captainHook.morality #=> "I'm evil!"
  wicketWitch.morality #=> "I'm evil!"
  wickedWitch.fly #=> "I'm flying!"


If we need to create more evil, flying fairy tale characters we can now use wickedWitch as our prototype:
The extend method only adds the functionality to the particular object it is invoked on, not to the class of that object.  The object "quadrilateral" is an instance of class Polygon and so is the object "triangle".  If the object "quadrilateral" is extended with the Area module then it will have access to the area method but the object "triangle" will not.


   dragon = wickedWitch.clone()
   triangle.area(10, 20) # => ERROR
  donKarnage = wickedWitch.clone() # You know, that guy from TailSpin...

Revision as of 03:06, 6 October 2010

Prototype-based object oriented programming is the method in which object behavior is defined by existing objects (or prototypes), not classes. In prototype-based programming (also called instance-based programming) prototypes are cloned to create extension objects.[1][4] Programmers then define the differences between the default behavior inherited from the prototype to create additional functionality for the extension object.[4]

All extension objects contain two parts: a list of pointers to their prototype objects, and a set of instructions unique to itself. When a method invocation is sent to an extension object, the object first looks to see if the method is defined in its own set of instructions. If the method is not found within the objects own code, it then looks for the method among the object's prototype methods, and so on. This system of method invocation is called delegation. Programming languages without delegation cannot implement prototype-based programming.[4] The examples in this article will use the Ruby programming language.

JavaScript, Self, Io, NewtonScript, Omega, Cecil, Lua, Object-Lisp, Examplars, Agora, ACT-I, Kevo, Moostrap, Obliq, Garnet [5]

In Ruby, you can define an extension object's prototype by using the SimpleDelegator class. In order to use the SimpleDelegator class you must include the delegate file. In this example we create two instances of class Polygon:

 require 'delegate'
 class Polygon
   attr_reader :sides
   def initialize(sides)
     @sides = sides
   end
 end
 quadrilateral = Polygon.new(4)
 triangle = Polygon.new(3)

Next we create an extension object called rectangle using quadrilateral as our prototype. As I said before, we use the SimpleDelegator class and pass the prototype as the constructor argument:

 rectangle = SimpleDelegator.new(quadrilateral)
 puts rectangle.sides # => 4

To add functionality in our inheritance hierarchy we use the extend method. The extend method will add functionality to a particular instance of a class:

 module Area
 def area(length, width)
   length * width
 end
 quadrilateral.extend(Area)
 puts rectangle.area(10, 20) # => 200

According to the definition of delegation, if the method invoked is not part of the calling object then it attempts to find the method in the prototype object. Since the area method is not a part of the rectangle object the program then looks for the method in the prototype, quadrilateral.

The extend method only adds the functionality to the particular object it is invoked on, not to the class of that object. The object "quadrilateral" is an instance of class Polygon and so is the object "triangle". If the object "quadrilateral" is extended with the Area module then it will have access to the area method but the object "triangle" will not.

 triangle.area(10, 20) # => ERROR