In continuation with this question,
Animal
class has four fields:
name
sound
owner
favFood
Cat
derived class has one field
mode
Derived class
Cat
is created such that every instance ofCat
inherits instance members ofAnimal
. In addition,Cat
adds a new instance membermode
.Constructor pattern is used amidst construction and modification of objects.
Criteria is,
Animal
andCat
class should enforce encapsulation and proper inheritance.
Solution
/* example.js */
function Animal() {
var _name = "";
var _sound = "";
var _owner = "";
var _favFood = "";
Object.defineProperties(this, {
'name': {
get: function () {
return _name;
},
set: function (name) {
//check conditions before setting the name
_name = name;
}
},
'owner': {
get: function () {
return _owner;
},
set: function (ownerName) {
//check conditions before setting the owner
_owner = ownerName;
}
},
'sound': {
get: function () {
return _sound;
},
set: function (sound) {
//check conditions before setting the sound
_sound = sound;
}
},
'favFood': {
get: function () {
return _favFood;
},
set: function (favFood) {
//check conditions before setting the name favFood
_favFood = favFood;
}
}
});
}
//Below code is the interface for Animal and its subclass type objects
Animal.prototype.getName = function(){ return name;} // calls get property of name
Animal.prototype.setName = function(newName){name = newName;} //calls set property of name
Animal.prototype.getOwner = function(){ return owner;}
Animal.prototype.setOwner = function(newOwner){owner = newOwner;}
Animal.prototype.getSound = function(){ return sound;}
Animal.prototype.setSound = function(voice){ sound = voice;}
Animal.prototype.getFavFood = function(){ return favFood;}
Animal.prototype.setFavFood = function(food){ favFood = food;}
/* dog.__proto__ points to Animal.prototype */
var animal = new Animal();
animal.setName("Spot");
animal.setOwner("Paul");
animal.setSound();
document.write("Animal properties:" + "<br>");
document.write(animal.getName() + "<br>");
document.write(animal.getOwner() + "<br>");
document.write(animal.getSound() + "<br><br><br>");
/* Cat.__proto__ points to Function.prototype */
function Cat() {
/*
Below line will add definePropertiess name/sound/owner/favFood
to an instance i.e., Cat()
*/
Animal.call(this);
var _mode = "";
Object.defineProperties(this, {
'mode': {
get: function () {
return _mode;
},
set: function (newMode) {
//check conditions before setting the sound
_mode = newMode;
}
}
});
}
/*
After executing, below line of code,
Cat.prototype.__proto__ will point to Animal.prototype;
*/
Cat.prototype = Object.create(Animal.prototype);
/*
In the above line, when Cat.prototype.__proto__ points to Animal.prototype,
Cat.prototype.constructor automatically points to Animal, so this below line
*/
Cat.prototype.constructor = Cat;
Cat.prototype.getMode = function(){ return mode;}
Cat.prototype.setMode = function(Mode){ mode = Mode;}
/* sophie.__proto__ points to Cat.prototype */
var sophie = new Cat();
sophie.setName("Sophie");
sophie.setOwner("Derek");
sophie.setSound("Meow");
document.write("Cat properties:" + "<br>");
document.write(sophie.getName() + "<br />");
document.write(sophie.getOwner() + "<br />");
document.write(sophie.getSound() + "<br />");
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Constructor pattern</title>
<script type="text/javascript" src="example.js"></script>
</head>
<body>
<noscript>
Requires JS
</noscript>
</body>
</html>
As per debugging, Animal.call(this)
gets invoked on new Cat()
instance, private members _name
/_owner
/_sound
/_favFood
are created separately for Cat
instance.
Using constructor pattern, Does this design enforce encapsulation and inheritance?
Note: Constructor pattern reference
prototype
property. Are you referring to terminology(Animal
class) used in this question? \$\endgroup\$ – overexchange Dec 28 '15 at 6:10setXXX
andgetXXX
methods are currently broken as they reference an implicit global object (in this case,window
). Your code will break once you have two instances of your class. \$\endgroup\$ – Dan Pantry Dec 28 '15 at 7:22window['name'] = 'Spot'
is defined, on callingAnimal.prototype.setName('Spot');
\$\endgroup\$ – overexchange Dec 28 '15 at 7:38