使用访问说明符public
,protected
和private
指定C ++中的继承。私有继承使基类的公共成员和受保护成员成为派生类的私有成员。
有没有办法在JavaScript中实现私有继承?
我知道JavaScript有基于原型的继承,所以如果有办法让基类的公共成员成为派生类的私有成员,我感到很困惑。
答案 0 :(得分:1)
这演示了C ++风格的“公共”,“受保护”和“私有”数据成员和成员函数。
function Base() {
'use strict';
/*--------------------------------------------------------------------------*/
/*Declare all data members here using 'this.' which makes them 'public', but
only in the scope of Base. */
function Core() {
this.private_data1 = 'private data1 of Base';
this.private_data2 = 'private data2 of Base';
this.protected_data1 = 'protected data1 of Base';
this.protected_data2 = 'protected data2 of Base';
this.public_data1 = 'public data1 of Base';
this.public_data2 = 'public data2 of Base';
}
/*--------------------------------------------------------------------------*/
/*Declare all member function here using 'Core.prototype.' which makes them
'public' too, but again only in the scope of Base. */
Core.prototype.private_function1 = function() {
console.log('private function1 of Base.');
};
Core.prototype.private_function2 = function() {
console.log('private function2 of Base.');
};
Core.prototype.protected_function1 = function() {
console.log('protected function1 of Base.');
};
Core.prototype.protected_function2 = function() {
console.log('protected function2 of Base.');
};
Core.prototype.public_function1 = function() {
console.log('public function1 of Base.');
/*We can call public, protected and private functions ...*/
this.protected_function1();
this.private_function1();
/*... and access public, protected and private from here ...*/
console.log(this.public_data1);
console.log(this.protected_data1);
console.log(this.private_data1);
/*... even if they're overloaded.*/
this.public_function2();
this.protected_function2();
this.private_function2();
console.log(this.public_data2);
console.log(this.protected_data2);
console.log(this.private_data2);
};
Core.prototype.public_function2 = function() {
console.log('public function2 of Base.');
};
/*--------------------------------------------------------------------------*/
/*Define visibility of the members. If you're editing the core, make sure that
each member is listed in no more and no less than one of these three
functions.*/
Core.prototype.grandPublicAccessTo = function(instance) {
instance.public_data1 = mCore.public_data1;
instance.public_data2 = mCore.public_data2;
instance.public_function1 = function() { mCore.public_function1(); }
instance.public_function2 = function() { mCore.public_function2(); }
}
Core.prototype.grandProtectedAccessTo = function(instance) {
this.grandPublicAccessTo(instance);
instance.protected_data1 = mCore.protected_data1;
instance.protected_data2 = mCore.protected_data2;
instance.protected_function1 = function() { mCore.protected_function1(); }
instance.protected_function2 = function() { mCore.protected_function2(); }
}
Core.prototype.grandPrivateAccessTo = function(instance) {
this.grandProtectedAccessTo(instance);
instance.private_data1 = mCore.private_data1;
instance.private_data2 = mCore.private_data2;
instance.private_function1 = function() { mCore.private_function1(); }
instance.private_function2 = function() { mCore.private_function2(); }
}
/*--------------------------------------------------------------------------*/
var mCore = new Core();
this.inherit = function(heir, core) {
/*Grand the base core access to every member of heir's core, and ... */
core.grandPrivateAccessTo(mCore);
/*... grand the heir's core access to public and protected members of the
base's core.*/
mCore.grandProtectedAccessTo(heir);
}
/*Grand public access to every instance of Base.*/
mCore.grandPublicAccessTo(this);
};
function Child() {
'use strict';
/*--------------------------------------------------------------------------*/
/*Declare a few data members to demonstrate that these mask the corresponding
members of Base.*/
function Core() {
this.private_data2 = 'private data2 of Child';
this.protected_data2 = 'protected data2 of Child';
this.public_data2 = 'public data2 of Child';
}
/*Overload some member functions to demonstrate that too.*/
Core.prototype.private_function2 = function() {
console.log('private function2 of Child.');
};
Core.prototype.protected_function2 = function() {
console.log('protected function2 of Child.');
};
Core.prototype.public_function2 = function() {
console.log('public function2 of Child.');
};
/*--------------------------------------------------------------------------*/
/*Define visibility of the members. If you're editing the core, make sure that
each member is listed in no more and no less than one of these three
functions.*/
Core.prototype.grandPublicAccessTo = function(instance) {
instance.public_data2 = mCore.public_data2;
instance.public_function2 = function() { mCore.public_function2(); }
}
Core.prototype.grandProtectedAccessTo = function(instance) {
this.grandPublicAccessTo(instance);
instance.protected_data2 = mCore.protected_data2;
instance.protected_function2 = function() { mCore.protected_function2(); }
}
Core.prototype.grandPrivateAccessTo = function(instance) {
this.grandProtectedAccessTo(instance);
instance.private_data2 = mCore.private_data2;
instance.private_function2 = function() { mCore.private_function2(); }
}
/*--------------------------------------------------------------------------*/
var mCore = new Core();
/*Inherit from Base. Multiple inheritance is possible.*/
var base = new Base();
base.inherit(this, mCore);
/*Grand public access to every instance of Child.*/
mCore.grandPublicAccessTo(this);
};
function main() {
'use strict';
console.log('testing base');
var base = new Base();
base.public_function1();
/*Thinks like this:
base.private_function1();
would result in a TypeError.*/
console.log('testing child');
var child = new Child();
child.public_function1();
}
main();
输出:
测试基地
基地的公共功能1
保护功能1的基础。
基地的私人功能1
基地公共数据1
基数的受保护数据1
基地的私人数据1
基地的公共功能2
Base的受保护功能2
基地的私人功能2
基地公共数据2
基数的受保护数据2
基地的私人数据2
测试孩子
基地的公共功能1
保护功能1的基础。
基地的私人功能1
基地公共数据1
基数的受保护数据1
基地的私人数据1
儿童的公共功能2
儿童的受保护功能2
儿童的私人功能2
儿童的公共数据2
儿童的受保护数据2
儿童的私人数据2
答案 1 :(得分:0)
在派生类构造函数调用基类构造函数的位置继承基类的实例属性。此时,需要继承的基类的所有实例属性 privately 可以作为局部变量存储在派生类的构造函数中,并随后从派生类的实例。
这种技术显然不适用于从基类原型继承的属性。然而,这适用于我的用例,因此我在这里分享它。
在下面的示例中,派生类ChocolateCake
私有 从基类setBakingTemperature
继承成员Cake
。< / p>
function Cake() {
var bakingTemperature = 250;
this.setBakingTemperature = function(temperature) {
bakingTemperature = Math.min(temperature, 400);
}
this.getBakingTemperature = function() {
return bakingTemperature;
}
}
Cake.prototype.bake = function() {
console.log("Baking the cake at " + this.getBakingTemperature() + " °C");
}
function ChocolateCake() {
Cake.call(this);
/* inherit 'setBakingTemperature' privately */
var setBakingTemperature = this.setBakingTemperature;
delete this.setBakingTemperature;
setBakingTemperature(300);
}
ChocolateCake.prototype = Object.create(Cake.prototype, {
constructor: {value: ChocolateCake}
});
var chocolateCake = new ChocolateCake();
chocolateCake.setBakingTemperature(); /* throws TypeError exception */
chocolateCake.getBakingTemperature(); /* 300 */
chocolateCake.bake(); /* Baking the cake at 300 °C */
更新:
使用@ p.kamps的想法,还有另一种方法可以实现这一目标。这种方法的优点是子类可以选择要从基类继承的属性,而不需要关心其他属性。
var Cake = function() {
var bakingTemperature = 250;
var setBakingTemperature = function(temperature) {
bakingTemperature = Math.min(temperature, 400);
}
this.inheritSetBakingTemperature = function() {
if (this instanceof Cake) {
return setBakingTemperature;
}
return null;
}
this.getBakingTemperature = function() {
return bakingTemperature;
}
}
Cake.prototype.bake = function() {
console.log("Baking the cake at " + this.getBakingTemperature() + " °C");
}
var ChocolateCake = function() {
Cake.call(this);
/* inherit 'setBakingTemperature' privately */
var setBakingTemperature = this.inheritSetBakingTemperature();
setBakingTemperature(300);
}
ChocolateCake.prototype = Object.create(Cake.prototype, {
constructor: {value: ChocolateCake}
});
var chocolateCake = new ChocolateCake();
chocolateCake.setBakingTemperature(); /* throws TypeError exception */
chocolateCake.getBakingTemperature(); /* 300 */
chocolateCake.bake(); /* Baking the cake at 300 °C */
答案 2 :(得分:-1)
JavaScript中任何对象的私有成员都在函数中定义,该函数将对象本身创建为函数的变量,因此这些变量只能在引用变量的对象的方法中可见,这要归功于Clousure
function Person (age) {
var age = age;
this.name = 'Robert';
this.isAdult = function () {
return age > 17;
};
}
在上面的代码中,年龄属性&#39;它是私有的,非常私密,实际上无法修改,你唯一可以做的就是用isAdult方法检查它是否大于17。
在SubClass构造函数中实现它几乎是一回事,你只需要定义原型的属性,你就不能将private作为构造函数中的变量来定义,并定义对象的方法。也可以在构造函数中访问该属性。