Programming on a Jerker PART 4: Laughing at the Deadly Diamond Problem or: How I learned to love mulitple inheritence

Warning: this is a post entirely for those Jerkers, I mean “Jerks”, who program JavaScript at their Ikea desks.

Inheritance with classes is difficult because you have two programming entities that must be kept in sync; your program and the program’s class taxonomy. Any changes to the class taxonomy will cascade into the program, and vice versa. With classless JavaScript there is no taxonomy, thus there is only one thing to change, the program. And, the program will always be consistent within itself.

A graphical representation of the objects in the program below could be:

Animal
  Snake
  Bird
    Duck
  Mammal
    Platypus

But this would not capture the fact that the Platypus is closely programmatically related to both the Snake and Duck. The platypus inherits its egg laying ability from the Snake, and its bill from the Duck.

The example program below shows how to easily accomplish multiple [inheritance] in non-prototype based JavaScript OOP. Code superfluous to the example has been stripped away.

console.clear();
function privitizeNewVariables(specs) {
  if (!specs.is_private) {
    var members = Object.assign({}, specs);
    members.is_private = true;
    return members;
  }
  return specs;
}
function newAnimal(specs) {
  var members = privitizeNewVariables(specs);
  var bodyDescription = function () {
    var body_description = members.common_name + ' : ';
    if (members.color_scheme) {
      body_description += members.color_scheme + ',';
    }
    if (members.body_covering) {
      body_description += members.body_covering + ',';
    }
    if (members.eat_with) {
      body_description += members.eat_with + ',';
    }
    return body_description;
  };
  return Object.freeze({
    bodyDescription: bodyDescription
  });
}
function newSnake(specs){
  var members = privitizeNewVariables(specs);
  members.makeOffspring = function () {
    console.log('Offspring by: laying eggs')
  }
  var an_animal = newAnimal(members);
  return Object.freeze({
    makeOffspring: members.makeOffspring
  });
}
function newBird(spec) {
  var members = privitizeNewVariables(spec);
  var an_animal = newAnimal(members);
  return Object.freeze({
  });
}
function newDuck(spec) {
  var members = privitizeNewVariables(spec);
  members.eat_with ='bill';
  var an_animal = newBird(members);
  return Object.freeze({
    eat_with: members.eat_with,
  });
}
function newMammal(spec) {
  var members = privitizeNewVariables(spec);
  if (!members.hasOwnProperty('body_covering')) {
    members.body_covering ='fur';
  }
  if (!members.hasOwnProperty('eat_with')) {
    members.eat_with ='teeth';
  }
  if (!members.hasOwnProperty('makeOffspring')) {
    members.makeOffspring = function () {
      console.log('Offspring by: gestating baby');
    }
  }
  var an_animal = newAnimal(members);
  return Object.freeze({
    bodyDescription: an_animal.bodyDescription,
    movesBy: members.movesBy,
    makeOffspring: members.makeOffspring,
  });
}
var egg_laying_snake = newSnake({common_name: 'borrowing egg laying'});
var duck_with_bill = newDuck({common_name: 'borrowing duck bill'});
var platypus_spec = {common_name: 'Platty the platypus',
    color_scheme : 'dark brown',
    eat_with: duck_with_bill.eat_with,
    movesBy: function (){ console.log('Moves by: swimming');},
    makeOffspring: egg_laying_snake.makeOffspring};
var a_platypus = newMammal(platypus_spec);

console.log(a_platypus.bodyDescription());
a_platypus.movesBy();
a_platypus.makeOffspring();

Here is the console output for the above:

Platty the platypus : dark brown,fur,bill,
Moves by: swimming
Offspring by: laying eggs

Explanation:

var egg_laying_snake = newSnake({common_name: 'borrowing egg laying'});
var duck_with_bill = newDuck({common_name: 'borrowing duck bill'});
var platypus_spec = {common_name: 'Platty the platypus',
    color_scheme : 'dark brown',
    eat_with: duck_with_bill.eat_with,
    movesBy: function (){ console.log('Moves by: swimming');},
    makeOffspring: egg_laying_snake.makeOffspring};
var a_platypus = newMammal(platypus_spec);

We create a Snake and a Duck object to borrow properties from. The platypus object takes the egg laying function of a Snake, and the value ‘bill’ for its ‘eat_with’ property and overrides the default Mammal properties. The platypus gets its ‘fur’ from being a mammal. Yep, it’s that simple.

Part  1  2  3  4  5  6  7

Leave a Reply

Your email address will not be published.