3

Take for example a multiple choice question game.

You have a MathQuestion and WordQuestion classes, should these implement an IQuestion interface, that defines say a question, answer, and difficulty functions OR is it more usual to extend a question base class, and override these functions?

Which is the more correct way of doing such things?

davivid
  • 5,910
  • 11
  • 42
  • 71

2 Answers2

2

It mostly depends on the exact specifics of your classes. If the classes functionality is radically different but share function/property names then an interface would be more appropriate. If the classes share a lot of common implementation, then it would be more appropriate to subclass.

From your description, the two classes seem to fit more into the category of "same function/properties" with different implementations and would probably be better off with an interface.

I generally use interfaces are too enforce a common behavior that a group of classes share whereas sub-classing is more appropriately used in cases where you can achieve serious code re-use through inherited functions/properties. At the end of the day it's mostly a design choice.

Snukus
  • 1,302
  • 9
  • 17
  • Right that was what I was thinking, the classes both need questions and answers, but the Math class would be generating calculations whereas the Word class would be querying a DB. – davivid May 16 '11 at 17:19
2

Here's another way of thinking about the problem - is there actually any different between a MathQuestion and a WordQuestion? To me, it sounds like they are both Question objects and you could differentiate between the different types via composition.

You could start by defining an Enum class which lists the different types of Questions which appear in your Quiz (strictly speaking ActionScript 3 does not have proper Enums, but we can still achieve type safety with the following code.)

public class QuestionType {
    public static const MATH : QuestionType = new QuestionType("math");
    public static const WORLD : QuestionType = new QuestionType("world");

    private var _name : String;

    // Private constructor, do no instantiate new instances.
    public function QuestionType(name : String) {
        _name = name;
    }

    public function toString() : String {
        return _name;
    }
} 

You can then pass one of the QuestionType constants to the Question Class when you construct it:

public class Question {
    private var _message : String /* Which country is Paris the capital of? */
    private var _answers : Vector.<Answer>; /* List of possible Answer objects */
    private var _correctAnswer : Answer; /* The expected Answer */
    private var _type : QuestionType; /* What type of question is this? */

    public function Question(message : String, 
                              answers : Vector.<Answer>, 
                              correctAnswer : Answer, 
                              type : QuestionType) {
        _message = message;
        _answers = answers.concat(); // defensive copy to avoid modification.
        _correctAnswer = correctAnswer;
        _type = type;
    }

    public function getType() : QuestionType {
        return _type;
    }
}

Finally, a client (the code which makes use of the Question object) can query the question type easily:

public class QuizView extends Sprite {
    public function displayQuestion(question : Question) : void {
        // Change the background to reflect the QuestionType.
        switch(question.type) {
            case QuestionType.WORLD:
                _backgroundClip.gotoAndStop("world_background");
                break;

            case QuestionType.MATH:
                _backgroundClip.gotoAndStop("math_background");
                break;
        }
    }
}
Community
  • 1
  • 1
JonnyReeves
  • 6,119
  • 2
  • 26
  • 28
  • Wow thanks some great advice there. Although I do think for what I have in mind the question objects would be quite different, Math would generate various calculations whereas Word would query a DB. – davivid May 16 '11 at 17:18