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() 正在为您的 StateLearnConstructorStateExamConstructor 分配函数后覆盖 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" 应该会按预期工作。

demo

注意:您对 extend() 的实施比需要的更复杂。继承原型的现代方法是使用 Object.create():

function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype;
}