Overview
Object inheritance is something that many Object Oriented Programmers (OOP) have grown to love. We find it useful too. So, we thought it good to give you a head start on how this all works in Axiom Stack. It's actually fairly simple. So let's jump in.
For this tutorial we'll setup the scenario like this:
- We have two prototypes
- Base
- Page
- We have a number of other prototypes and a completely working system
The Beginning
I'm a Little Object
The start of the inheritance chain is with Object. Everything in our system is an Object. This makes sense when you think about Javascript in that functions and data alike are Objects.
Prototypes? Que?
In Axiom Stack prototypes are your Object types. This means that when you create that directory in your application root called Page, you've created a prototype called Page. It is important to understand this as we'll continually use this terminology throughout our tutorials and documentation.
Mozilla has great article discussing the differences in Class and Prototype based languages. Take a read there if you're interested in learning a bit more.
Example:
var ObjType1 = function() {
this.a = 1;
}
var ObjType2 = function() {
this.b = 2;
}
ObjType2.prototype = new ObjType1();
console.log((new ObjType2()).a); You should get back '1'.
AxiomObject
AxiomObject is a special Prototype. For most of us, this will be the beginning of the inheritance chain. We discourage from mucking around with the "Object" type as to avoid conflict and confusion later on in your development cycle. You will get to a point where you want to apply a function, tal file, or property to all of your prototypes. Pragmatically you should only do this once in your code base. You can do this on AxiomObject.
Keep in mind that AxiomObject, like Object in Java, is implicitly inherited. Meaning, any methods or properties you place on AxiomObject will be available to all prototypes. While not a huge ordeal, you will need to take care in your application design so that you don't pollute the namespaces of your prototypes and so that you aren't adding unnecessary weight to your objects.
Pragmatic Prototypes
You've heard about default inheritance. But, what about explicit inheritance? We have that too. We follow the Java notion of extension. This means that you can only ever extend a single prototype. This is also similar to the Javascript notion of OOP.
Let's setup this scenario. You have a base object that you want to use for all objects that are traversable, meaning you can access them from a URL (http://localhost/
In Java, class extension is represented like the following:
class Section extends Page {
} In Javascript, class extension looks like this:
var Page = function() {};
var Section = function () {};
Section.prototype = new Page(); If you are still a bit confused on the Prototype piece, take a look at this prototype explanation with an eye towards OOP.
But, the way we do this in Axiom Stack is to just put a line in your prototype.properties file.
# Section/prototype.properties _extends = Page
What we showed you above for JS or Java is all taken care of for you behind the scenes. You just need to put that line in your prototype.properties file to acquire all the properties and functions of the super prototype.
It Lives
Above is a lot of theory and "how it works" kind of chatter. But, what about a working example? How does this actually get put into a product system?
AxiomObject
# AxiomObject/prototype.properties _children _children.type = Collection(AxiomObject) _children.accessname = id id id.type = String title title.type = String
Page
# Page/prototype.properties body body.type = XHTML
/*
* Page/functions.js
*/
function inheritedFunc() {
return "Inheriting 'inheritedFunc' from Page; ";
} Section
# Section/prototype.properties _extends = Page _children.type = Collection(Page)
/*
* Section/functions.js
*/
function func() {
return "The object calling this function is a Section; " + this.inheritedFunc();
} What Am I?
While we've discussed the setup and creation of prototypes and how they inherit properties, it is only part of the picture. The whole story has another part.
It is often the case that you have no idea what object you have. If you use the query API successfully, you'll get an array of objects that could be of mixed types. But, maybe you have a function only available on a certain type? Let's look at the ways to handle this.
Assume that Section has a function named func.
instanceof
if (obj instanceof Section) {
return obj.func();
} typeof
if (typeof obj == "section") {
return obj.func();
} _prototype
if (obj._prototype == "Section") {
return obj.func();
} obj.func
if (obj.func) {
return obj.func();
} That's It
Now you should understand how inheritance works in Axiom Stack. Go forth and conquer!

