A comparison of Prototype-based and class-based inheritance
Introduction
This document is a mix of different posts on the Io mailing list. It tries to expose the differences (and advantages) between a prototype-based inheritance (PBI) and a class-based inheritance (CBI). You can have a look at the IoLanguage page for more information on what those both types of inheritance are.
Differences in the conception
MikeAustin? suggests that it can be easier to refactor in a prototype-based language. In CBI you have first to abstract the object and create a class that will serve to create instances, while in PBI you have to create an instance (the prototype) that you can update gracefully according to your design needs.
Refactoring can occur at runtime, thanks to the dynamic nature of prototype-based languages, which could allow in a video game, as Mike states, to completely change a monster's AI (Artificial Intelligence) without having to recreate the object associated to the monster.
In some cases, object oriented languages can also have these dynamic properties. In many of the more advanced OO languages, such as Smalltalk, Ruby, and Python, both objects and classes can be mutated anywhere in the program. Any mutation to the class is passed on to the object dynamically.
Differences in traits
Realising PBI implies that the languages considers operations (blocks, methods) as first-class values. This means that operations can be referenced and moved across objet. This trait make prototype-based language more versatile that class-based languages, which do not need to manipulate the operations, which are already defined in classes.
All in all, in PBI, operations are bound to an object, while in CBI, operations are bound to a class.
Classes and prototypes are models
Prototypes and classes seem to be very close concepts, if not two perspectives of the same thing. The concept behind both is to factorise structural and operational similarities between objet by expressing models. A class can be considered as an object factory, ie. an object that creates other objects. The constructors of a class allow to create a new object that will be based on the model defined by the class (that is which attributes and operations the object should define).
On the other hand, a prototype can also be considered as a model for other objects, as cloning an object (which is then the prototype) means that the new object will have the same attributes and resolve its undefined operations in the prototype (this depends on the prototype-based language object model).
Classes and objects are not of the same type
While prototypes and classes are two ways of expressing a model, an abstraction of similarities between instances, the main difference between prototypes and classes is that classes are a special kind of object, which implies that constructing an object and constructing a class is not made the same way.
This means that the flexibility of CBI lies in the API offered by the Class object (when it is an object, which implies that the language has some reflectivity). If operations like derive(), addMethod(), etc are possible (which also imply that operations can be created an manipulated as other values), it should be possible to dynamically create new classes or modify existing new ones -- but this implies that the language is reflective (to access the Class objects) and that it allows to references operations (to create an manipualte operations).
On the other hand, prototype-based language cannot be realised without those two features, which make them more generic and versatile.
Duplication vs Construction
Steve Dekorte sums well the difference between classes (which construct objects) and prototypes (which are the construction information):
I see the distinction as duplication vs. construction. Consider the metaphor: house = instance blueprint = class (followed to construct a house instance) prototype house = prototype (duplicated to make a house instance) A house isn't inter-changable with a blueprint(you can't live in a blue print), just as a class is not inter-changable with an instance. While a prototype house *is* inter-changable with an instance, in the sense that you can live in a prototype house and it behaves the same way. The beauty of prototypes is that they eliminate a cumbersome and unnecessary abstraction.
I think this sums up things well, and implies that PBI is more generic than CBI, because CBI can be build with PBI, but it is difficult for CBI to build PBI, because CBI is much more specialised.
