Javascript 继承和函数覆盖
Javascript inheritance and function overriding
// Base state class -------------------------
function StateConstuctor()
{
}
// Inherited learn class --------------------
function StateLearnConstructor()
{
}
// Inherited exam class ---------------------
function StateExamConstructor()
{
}
function extend(Child, Parent)
{
var F = function() { }
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
Child.superclass = Parent.prototype
}
function createState(rollType)
{
if (rollType == 'learn')
{
extend(StateLearnConstructor, StateConstuctor);
var state = new StateLearnConstructor();
return state;
}
else if (rollType == 'exam')
{
extend(StateExamConstructor, StateConstuctor);
var state = new StateExamConstructor();
return state;
}
}
StateConstuctor.prototype.getTitles = function()
{
console.log('base "virtual" function');
}
StateLearnConstructor.prototype.getTitles = function()
{
console.log('learn');
}
StateExamConstructor.prototype.getTitles = function()
{
console.log('exam');
}
你好,我有以下 "OOP" 结构,我想在 C++ 中模拟类似虚函数的东西。所以我在 StateConstructor
中有基本虚函数,每个子类都有不同的实现。
var state = createState('exam');
state.getTitles();
但是这段代码调用了 StateConstructor
基本虚函数。这里有什么问题?
createState()
正在为您的 StateLearnConstructor
和 StateExamConstructor
分配函数后覆盖 prototype
。
您不应该有条件地延长它们。只需扩展它们:
extend(StateLearnConstructor, StateConstuctor);
extend(StateExamConstructor, StateConstuctor);
StateConstuctor.prototype.getTitles = function () {
console.log('base "virtual" function');
};
StateLearnConstructor.prototype.getTitles = function () {
console.log('learn');
};
StateExamConstructor.prototype.getTitles = function () {
console.log('exam');
};
function createState(rollType) {
if (rollType == 'learn') {
return new StateLearnConstructor();
} else if (rollType == 'exam') {
return new StateExamConstructor();
}
}
完成后,您的 "virtual functions" 应该会按预期工作。
注意:您对 extend()
的实施比需要的更复杂。继承原型的现代方法是使用 Object.create()
:
function extend(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.superclass = Parent.prototype;
}
// Base state class -------------------------
function StateConstuctor()
{
}
// Inherited learn class --------------------
function StateLearnConstructor()
{
}
// Inherited exam class ---------------------
function StateExamConstructor()
{
}
function extend(Child, Parent)
{
var F = function() { }
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
Child.superclass = Parent.prototype
}
function createState(rollType)
{
if (rollType == 'learn')
{
extend(StateLearnConstructor, StateConstuctor);
var state = new StateLearnConstructor();
return state;
}
else if (rollType == 'exam')
{
extend(StateExamConstructor, StateConstuctor);
var state = new StateExamConstructor();
return state;
}
}
StateConstuctor.prototype.getTitles = function()
{
console.log('base "virtual" function');
}
StateLearnConstructor.prototype.getTitles = function()
{
console.log('learn');
}
StateExamConstructor.prototype.getTitles = function()
{
console.log('exam');
}
你好,我有以下 "OOP" 结构,我想在 C++ 中模拟类似虚函数的东西。所以我在 StateConstructor
中有基本虚函数,每个子类都有不同的实现。
var state = createState('exam');
state.getTitles();
但是这段代码调用了 StateConstructor
基本虚函数。这里有什么问题?
createState()
正在为您的 StateLearnConstructor
和 StateExamConstructor
分配函数后覆盖 prototype
。
您不应该有条件地延长它们。只需扩展它们:
extend(StateLearnConstructor, StateConstuctor);
extend(StateExamConstructor, StateConstuctor);
StateConstuctor.prototype.getTitles = function () {
console.log('base "virtual" function');
};
StateLearnConstructor.prototype.getTitles = function () {
console.log('learn');
};
StateExamConstructor.prototype.getTitles = function () {
console.log('exam');
};
function createState(rollType) {
if (rollType == 'learn') {
return new StateLearnConstructor();
} else if (rollType == 'exam') {
return new StateExamConstructor();
}
}
完成后,您的 "virtual functions" 应该会按预期工作。
注意:您对 extend()
的实施比需要的更复杂。继承原型的现代方法是使用 Object.create()
:
function extend(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.superclass = Parent.prototype;
}