Showing posts with label inheritance. Show all posts
Showing posts with label inheritance. Show all posts

Thursday, March 31, 2011

javascript object oriented programming 3 - inheritance

inheritance - more details

Let's review the simple inheritance example in my last  blog:

//constructor method
function Person(name, sex) {
       this.name = name;
       this.sex = sex;
   }
//define Person prototype 
Person.prototype = {
       getName: function() {
           return this.name;
       },
       getSex: function() {
           return this.sex;
       }
}
//define an Employee constructor method
function Employee(name, sex, employeeID) {
    this.name = name;
    this.sex = sex;
    this.employeeID = employeeID;
}

Employee.prototype = new Person();
Employee.prototype.getEmployeeID = function() {
    return this.employeeID;
};
As we said, there are some problems in this inheritance. Let's address these problems one by one.
1. When we create the Employee constructor method and protoype, we also have to create a Person instance. It is not reasonable and not efficient.
To fix this issue, we should try to inherit the prototype only. We should put reusable properties and methods into prototype. Let's change our code:
Employee.prototype = Person.prototype;

In this way, every time we create a new Employee object, it can access any methods and properties in Person's prototype too. And we don't need to instance a Person object.

2. Another problem is Employee's prototype is completely re defined, this will cause Employee's constructor is referencing to the wrong object. Try the code below:


var e = new Employee('henry', 'm', 25);
console.log(e.constructor == Employee); //false
The constructor is not pointing to itself. To fix this issue, we simply change our code to this:
Employee.prototype = Person.prototype;
Employee.prototype.constructor = Employee.
3. Directly copying Person's prototype to Employee's prototype is easy and efficient. But it does bring some side effects. Employee's prototype is pointing to the same object, the Person's prototype, Employee's prototype properties and methods will complete override its parent object's prototype's same name properties and methods.
For example, if we also define a getName method in Employee's prototype:
Employee.prototype.getName = function(){return 'henry'};
var p = new Person('Jack', 'm');
p.getName(); //henry

To fix this issue, we must break the chain. We need to introduce an intermediary. We create an empty functoin F(){} first. Then we set its prototype to Person's prototype: F.prototype = Person.prototype. Now, let's see how we should do the inheritance:
function F(){};
F.prototype = Person.prototype;
Employee.prototype = new F();
Employee.prototype.constructor = Employee;

4. How to call parent object's method in child object? Javascript doesn't have someting like PHP's 'parent::' feature. There are several implementations for this. I just use a simple and traditional way: uber property. Finally the inheritance mechanism is:
var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;

What is the uber? Let's change our Person's getName method:
getName: function() {
var parentName = '';
if (this.constructor.uber) {
if (this.constructor.uber.getName) {
         parentName = this.getName();
}
   }
   return this.name + "'s parent is " + parentName;
}

Monday, March 28, 2011

javascript object oriented programming 2: inheritance

Inheritance - simple way

First, we need to know prototype. We can think prototype as a template. In javascript, everything is an object, every object has its own prototype.

A simple inheritance in javascript:
//constructor method
function Person(name, sex) {
       this.name = name;
       this.sex = sex;
   }
//define Person prototype 
Person.prototype = {
       getName: function() {
           return this.name;
       },
       getSex: function() {
           return this.sex;
       }
}
//define an Employee constructor method
function Employee(name, sex, employeeID) {
    this.name = name;
    this.sex = sex;
    this.employeeID = employeeID;
}
// Make Employee.prototype link to an instance of Person
// The Person instance can call the methods in Person prototype, so Employee's instances can access methods and properties of Person prototype as well.
Employee.prototype = new Person();
Employee.prototype.getEmployeeID = function() {
    return this.employeeID;
};
However, there are some problems with such a simple inheritance.
1. When we create the Employee constructor method and protoype, we also create a Person instance. That is not reasonable.
2. Employee's constructor method cannot access its parent/super class Person's constructor method.
3. Employee's constructor is pointing to the wrong place.
We will see how to address all these problems in my next blog.

Wednesday, March 23, 2011

PHP singleton inheritance

Prior to PHP 5.3, here is how we implement singleton:
class Service
{
private static $_instance = null;
private function __construct(){};
private function __clone(){};

public static function getInstance()
{
if (self::$_instance === null) {
self::$_instance = new self;
}
return self::$_instance;
}
}

However, we all know that it is very tricky if we want to extend/inherit this singleton class.
PHP 5.3 introduces LSB, which stands for Late Static Binding. It solves our problem of inheriting a singleton class. In PHP 5.3, we implement singleton in this way
class Service
{
private static $_instance = null;
private function __construct(){};
private function __clone(){};

public static function getInstance()
{
if (static::$_instance === null) {
static::$_instance = new static;
}
return static::$_instance;
}
}

Simply replace the 'self' keyword with 'static', we can inherit a singleton just like usual inheritance.

The difference is self keyword is bound to the referenced property or method at compile time. The self keyword points to the containing class and is unaware of subclasses. The static keyword forces PHP to bind to the code implementation at the latest possible moment.