我定义了以下BaseClass:
function BaseClass (arg1,arg2,arg3) {
//constructor code here then -
var privateVar = 7500;
this.getPrivateVar = function() { return privateVar; };
}
我希望有以下子类允许更改privateVar,如下所示:
function SubClass (arg1,arg2,arg3,privateVar) {
//constructor code here then -
var privateVar = privateVar;
}
SubClass.prototype = new BaseClass();
现在我希望SubClass继承getPrivateVar
方法。但是,当我尝试这个时,它总是返回7500
,它是BaseClass中的值而不是privateVar
的值。
换句话说,是否可以继承BaseClass的公共方法,但是它们中的任何引用都引用了SubClass的属性?我该怎么做?
通过事物的声音,这是不可能的。我的想法是为我的学生代码自动化代码检查器(我辅导孩子),但我只需要找到另一种方式。不管怎样,谢谢。
答案 0 :(得分:3)
您正在将Javascript对象模型与不互操作*的范围变量混合使用。
继承执行SubClass.prototype = new BaseClass();
的习惯用语只有在你自然地使用原型和构造函数时才有效:
function BaseClass(arg1, arg2, arg3) {
this._privateVar = 7500;
}
BaseClass.prototype.getPrivateVar = function() {
return this._privateVar;
};
function SubClass(arg1, arg2, arg3, privateVar) {
}
SubClass.prototype = new BaseClass();
//Better way to do it is
//SubClass.prototype = Object.create(BaseClass.prototype);
SubClass.prototype.constructor = SubClass;
在您认为任何人都可以通过编写_
来访问该属性之前,我可以争辩说任何人都可以通过使用反射来访问Java,PHP或C#中的任何私有。或者在Ruby中使用instance_eval
或send
等等。无论如何它都在你的手中。
*根据实施情况使用范围变量时,无或大部分都不起作用:
答案 1 :(得分:2)
您定义privateVar的方式使其成为BaseClass“构造函数”范围内的局部变量。像Neal说的那样,你不能从任何继承的类继承或“看”它。 您可以使用像Neal所说的闭包(但这可能是内存过度杀伤,具体取决于您的使用情况),或者使变量成为实例变量:
function BaseClass (arg1,arg2,arg3) {
//constructor code here then -
this.privateVar = 7500;
this.getPrivateVar = function() { return this.privateVar; };
}
function SubClass (arg1,arg2,arg3,privateVar) {
//constructor code here then -
this.privateVar = privateVar;
}
SubClass.prototype = new BaseClass();
var subClass = new SubClass(1,2,3,4000);
console.log(subClass.getPrivateVar());
答案 2 :(得分:2)
拥有private variable的想法是不应该在声明范围之外访问。但是,有几种方法可以实现您的目标。例如,您可以在privateVar
dynamic:
BaseClass
function BaseClass(arg1,arg2,arg3) {
var privateVar = BaseClass.privateVar;
this.getPrivateVar = function () {
return privateVar;
};
}
BaseClass.privateVar = 7500;
现在您可以按如下方式创建SubClass
:
function SubClass(arg1, arg2, arg3, privateVar) {
var args = Array.prototype.slice.call(arguments, 0, 3); // the first 3 args
var defaultPrivateVar = BaseClass.privateVar; // save the old value
BaseClass.privateVar = privateVar; // set a new default
BaseClass.call(this, args); // call super
BaseClass.privateVar = defaultPrivateVar; // restore old value
}
SubClass.prototype = Object.create(BaseClass.prototype); // inherit new way
现在您只需创建一个SubClass
的实例:http://jsfiddle.net/Pytkj/
答案 3 :(得分:0)
privateVar
是BaseClass
的局部变量。 不能由子类继承或更改。
您可以将父类和子类封装在同一范围内,如下所示:
(function(){
var privateVar = 7500;
function BaseClass (arg1,arg2,arg3) {
//constructor code here then -
this.getPrivateVar = function() { return privateVar; };
}
function SubClass (arg1,arg2,arg3,privateVar) {
//constructor code here then -
}
SubClass.prototype = new BaseClass();
return SubClass;
})();
答案 4 :(得分:0)
你不会。即使你可以,该财产也不能被称为“私人”。也许“受到保护”。
缺少不同访问级别的语言只使用公共属性和某种命名约定(比如调用它们__semiPrivateVar)。
有一些不同的解决方案,但它们在OO方面并不是真正可以描述的(你真正拥有的不是类和属性,而是构造函数,范围和变量)。
答案 5 :(得分:0)
继承BaseClass的公共方法但是它们中的任何引用都引用了SubClass的属性?
不,那是不可能的。在BaseClass
构造函数范围内创建的方法将始终引用该范围内的变量,您无法对其进行更改。它是变量,而不是对象的属性。
但是,你做的继承是错误的。您有一个BaseClass
实例,您可以从中继承所有SubClass
实例,并与之共享getPrivateVar
方法。给他们一个自己的!为此,您可以在子实例上应用父构造函数,创建新的闭包范围和新方法。并don't use new
!
function SubClass (arg1,arg2,arg3) {
BaseClass.call(this);
}
// or, if you need a reference to the variable:
function SubClass (arg1,arg2,arg3) {
// you have to create it on your own
var privateVar = arguments[3]; // or use a formal parameter
// and create `getPrivateVar` yourself
this.getPrivateVar = function() { return privateVar; };
}
SubClass.prototype = Object.create(BaseClass.prototype);