CSC/ECE 517 Fall 2010/ch3 2c jp: Difference between revisions
No edit summary |
|||
(15 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
= Prototype-based Inheritance = | = Prototype-based Inheritance = | ||
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][2] Programmers then define the differences between the default behavior inherited from the prototype to create additional functionality for the extension object.[2] | 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][2] Extension objects are objects that contain two parts: a list of pointers to their prototype objects, and a set of instructions unique to itself. Programmers then define the differences between the default behavior inherited from the prototype to create additional functionality for the extension object.[2] | ||
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.[2] | |||
Many programming languages, such as JavaScript, Self, Io, NewtonScript, Omega, Cecil, Lua, Object-Lisp, | Many programming languages, such as [http://en.wikipedia.org/wiki/JavaScript JavaScript], [http://en.wikipedia.org/wiki/Self_(programming_language) Self], [http://en.wikipedia.org/wiki/Io_(programming_language) Io], [http://en.wikipedia.org/wiki/NewtonScript NewtonScript], [http://en.wikipedia.org/wiki/Omega_(programming_language) Omega], [http://en.wikipedia.org/wiki/Cecil_(programming_language) Cecil], [http://en.wikipedia.org/wiki/Lua_(programming_language) Lua], [http://en.wikipedia.org/wiki/Object_Lisp Object-Lisp], [http://en.wikipedia.org/wiki/Agora_programming_language Agora], Kevo, Moostrap, [http://en.wikipedia.org/wiki/Obliq Obliq], and Garnet, allow for prototype-based inheritance.[3] Most sites will show [http://en.wikipedia.org/wiki/Prototype-based_programming examples in JavaScript]. The examples in this article will use the Ruby programming language. | ||
<br /> | <br /> | ||
Line 13: | Line 13: | ||
== Differences between class-based and prototype-based inheritance == | == Differences between class-based and prototype-based inheritance == | ||
Notice in | Notice in the example below that the only class defined was the Polygon class. If you were to implement this same example in a class-based inheritance you would need classes for Polygon, Quadrilateral, Triangle, and Rectangle: | ||
{| style="background: #F9F9F9;border: 1px solid #AAA; margin-right:auto;margin-left:auto;text-align:center;" | {| style="background: #F9F9F9;border: 1px solid #AAA; margin-right:auto;margin-left:auto;text-align:center;" | ||
Line 28: | Line 28: | ||
Another difference between class-based inheritance and prototype-based inheritance is the ability to add functionality to only a few particular objects. | Another difference between class-based inheritance and prototype-based inheritance is the ability to add functionality to only a few particular objects. To add functionality to the rectangle object with prototype-based inheritance, someone can simply extend that particular object. To add functionality to the rectangle object with class-based inheritance, you would need to create a new subclass just for the rectangle object. If many different types of objects are present this method could cause the class hierarchy to become verbose and overwhelming. | ||
== Delegation in Ruby == | == Delegation in Ruby == | ||
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 | 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' | require 'delegate' | ||
Line 45: | Line 44: | ||
triangle = Polygon.new(3) | triangle = Polygon.new(3) | ||
Next we create an extension object called rectangle using quadrilateral as our prototype. | Next we create an extension object called rectangle using quadrilateral as our prototype. We use the SimpleDelegator class and pass the prototype as the constructor argument: | ||
rectangle = SimpleDelegator.new(quadrilateral) | rectangle = SimpleDelegator.new(quadrilateral) | ||
Line 66: | Line 65: | ||
triangle.area(10, 20) # => ERROR | triangle.area(10, 20) # => ERROR | ||
==Conclusion== | |||
In smaller systems, where you are instantiating only one or a few of each type of object it is usually better to go the route of prototype based inheritance rather than class-based inheritance. By removing the need for creating class definitions you can make these smaller systems more concise and more simple. You can also add functionality to one object without affecting other objects or creating a need for subclasses. [4] | |||
==References== | ==References== | ||
[1] [http://en.wikipedia.org/wiki/Prototype-based_programming ''Prototype-based programming''] | [1] [http://en.wikipedia.org/wiki/Prototype-based_programming ''Prototype-based programming''] | ||
[2] Henry Lieberman | [2] Henry Lieberman, [http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html ''Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems''], Conference proceedings on Object-oriented programming systems, languages and applications, p.214-223, September 29-October 02, 1986, Portland, Oregon, United States | ||
[3] A. Lienhard, O. Nierstrasz. University of Bern. [http://www.slideshare.net/lienhard/prototypebased-programming-with-javascript#text-version ''Prototype-based Programming with JavaScript''] | [3] A. Lienhard, O. Nierstrasz. University of Bern. [http://www.slideshare.net/lienhard/prototypebased-programming-with-javascript#text-version ''Prototype-based Programming with JavaScript''] | ||
[4] Bosch P., [http://webcache.googleusercontent.com/search?q=cache:l4hNE4pVQ2wJ:python.org/ftp/python/doc/delegation.ps+better+to+use+prototype+based+inheritance+or+class+based+inheritance&cd=8&hl=en&ct=clnk&gl=us ''Inheritance vs. delegation: Is one better than the other?''] Unpublished. |
Latest revision as of 18:53, 27 October 2010
Prototype-based Inheritance
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][2] Extension objects are objects that contain two parts: a list of pointers to their prototype objects, and a set of instructions unique to itself. Programmers then define the differences between the default behavior inherited from the prototype to create additional functionality for the extension object.[2]
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.[2]
Many programming languages, such as JavaScript, Self, Io, NewtonScript, Omega, Cecil, Lua, Object-Lisp, Agora, Kevo, Moostrap, Obliq, and Garnet, allow for prototype-based inheritance.[3] Most sites will show examples in JavaScript. The examples in this article will use the Ruby programming language.
Differences between class-based and prototype-based inheritance
Notice in the example below that the only class defined was the Polygon class. If you were to implement this same example in a class-based inheritance you would need classes for Polygon, Quadrilateral, Triangle, and Rectangle:
Class-based Inheritance |
---|
Prototype-based Inheritance |
---|
Another difference between class-based inheritance and prototype-based inheritance is the ability to add functionality to only a few particular objects. To add functionality to the rectangle object with prototype-based inheritance, someone can simply extend that particular object. To add functionality to the rectangle object with class-based inheritance, you would need to create a new subclass just for the rectangle object. If many different types of objects are present this method could cause the class hierarchy to become verbose and overwhelming.
Delegation in Ruby
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. We use the SimpleDelegator class and pass the prototype as the constructor argument:
rectangle = SimpleDelegator.new(quadrilateral) puts rectangle.sides # => 4
Extend Method
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
Conclusion
In smaller systems, where you are instantiating only one or a few of each type of object it is usually better to go the route of prototype based inheritance rather than class-based inheritance. By removing the need for creating class definitions you can make these smaller systems more concise and more simple. You can also add functionality to one object without affecting other objects or creating a need for subclasses. [4]
References
[1] Prototype-based programming
[2] Henry Lieberman, Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems, Conference proceedings on Object-oriented programming systems, languages and applications, p.214-223, September 29-October 02, 1986, Portland, Oregon, United States
[3] A. Lienhard, O. Nierstrasz. University of Bern. Prototype-based Programming with JavaScript
[4] Bosch P., Inheritance vs. delegation: Is one better than the other? Unpublished.