1
// 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');
}

Hello, I have the following "OOP" structure and I want to emulate something like virtual functions in C++. So I have base virtual function in StateConstructor and different realizations for each subclass.

var state = createState('exam');
state.getTitles();

But this code calls StateConstructor base virtual function. What's wrong here?

4
  • StateConstuctor is not called. fiddle Commented Jan 2, 2015 at 20:36
  • @Oriol - Isn't that the point though? The mixed inheritance sets the prototype of StateConstructor to state, but the constructor that gets called is the exam constructor as shown in the code. Commented Jan 2, 2015 at 20:42
  • @TravisJ Not sure how it is supposed to work, but OP says "this code calls StateConstructor". And I can't reproduce that. Commented Jan 2, 2015 at 20:43
  • @Oriol No, OP said "this code calls StateConstructor base virtual function". In other words "this code calls the base virtual function on StateConstructor". Commented Jan 2, 2015 at 20:53

1 Answer 1

2

createState() is overwriting the prototypes for your StateLearnConstructor and your StateExamConstructor after you have assigned functions to them.

You shouldn't be conditionally extending them. Just extend them:

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();
    }
}

Once you do that, your "virtual functions" should work as expected.

demo

Note: Your implementation for extend() is more complicated than it needs to be. The modern way to inherit a prototype is to use Object.create():

function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.