1

I am trying to create a class. Let's call it Questionnaire. In Questionnaire, I want to instantiate a number of classes called Question. The constructor for Questionnaire accepts a string array of words, and for each word, there should be a Question class to accept it as an argument for its constructor. In other words, for every string that is passed as an argument, I want to create a Question.

I need to be able to put Questionnaire within a bigger class and still call the methods of the Question classes. The size of the array passed to Questionnaire varies as well. I don't know how I can put multiple classes within another class when I don't know how many classes there will be, and how to reference them from an outer class. If the array was a fixed length I'd just create Questions as question1, question2, question3... but since this is not the case I am not sure anymore. I do know there is a maximum number of Question classes I want to create though.

edit: I'm using J2ME CDLC 1.1 MIDP 2.0 for this (it's part of a mobile phone app) so my solutions are constrained by what it offers.

5 Answers 5

4

You don't want to have a separate variable per question - use a List<Question> to have one variable which refers to a collection of questions:

public class Questionnaire
{
    private final List<Question> questions;

    public Questionnaire(String[] words)
    {
        questions = new ArrayList<Question>();
        for (String word : words)
        {
            questions.add(new Question(word));
        }
    }

    // Use questions here
}

EDIT: If you're in an environment without generics, you could use the non-generic form, like this:

    private final List questions;

    public Questionnaire(String[] words)
    {
        questions = new ArrayList();
        for (String word : words)
        {
            questions.add(new Question(word));
        }
    }

or like this if you don't have List/ArrayList:

    private final Vector questions;

    public Questionnaire(String[] words)
    {
        questions = new Vector();
        for (String word : words)
        {
            questions.add(new Question(word));
        }
    }

In either case you'll need to cast on every access. Alternatively, you could use an array:

    private final Question[] questions;

    public Questionnaire(String[] words)
    {
        questions = new Question[words.length];
        for (int i = 0; i < words.length; i++)
        {
            questions[i] = new Question(word);
        }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

questions = new ArrayList<Question>(); perhaps? List is an interface after all. Given the newbie tag, probably worth specifying the need for import java.util.*; (or more specific imports) as well
Jon, that's using generics, isn't it? Ugh, I should probably have mentioned I am working with J2ME. I don't think it supports generics.
@barrowc: Doh, fixed. That'll teach me to answer Java questions in the middle of writing a chapter about .NET generic collections :) @colig: In that case, you could use the raw type. Will edit.
@colig: I would strongly advise that if you're new to Java, learning in J2ME isn't a great idea. I suggest you start off by learning the basics with the desktop framework, and then move onto J2ME. Aside from anything else, it's a lot easier to just experiment without having to worry about emulators etc.
@LES2: Did you read where the OP said that he's using J2ME, and the bit where I said "if you're in an environment without generics"? I wouldn't be mentioning nongeneric types without good reason...
|
1

As J2ME API lacks the Collections API, your best bet is to grab a Vector.

Vector questions = new Vector();
for (int i = 0; i < words.length; i++) {
    questions.addElement(new Question(words[i]));
}

Comments

0

You probably want to go with a Set of questions rather than List. Try :

private final Set<Question> questions;

This will prevent duplicate questions. Everything else will be the same as JonSkeet's answer.

Comments

-1

Why don't you use a List on the questionaire and for each question you add you add one to the List, for example.

public class Questionnaire
{
    public List<Question> myQuestions {get; private set;}

    public Questionnaire(string[] questions)
    {

       myQuestions = new List<Questions>();

       foreach(string q in questions)
       {
          myQuestions.Add(new Question {questionText = g});
       }
    }
}
public class Question
{
    public string questionText {get; set;}
}

Then you will be able to check the questions from outside... this is what you want?

Hope this helps

EDIT: ohh is Java, but you got the idea right?

4 Comments

As with the other answer above, List is an interface so new List<Questions>(); is incorrect. List should be ArrayList (or other class which implements the List interface and <Questions> should be <Question>
Also the get; private set; and get; set; parts don't seem to be Java. C# maybe?
the poor guy barely knows java and here you are berating him with C#?
Guys, ideas, concepts, Im showing that, if you need all done go somewhere else...
-1
import java.util.*;

public class Questionnaire implements Iterable<Question> {
    private final List<Question> questions;

    public Questionnaire(String ...words) {
       questions = new ArrayList<Question>(words.length);
       for(String word : words) {
           questions.add(new Question(word));
       }
    }

    // allows you to use a Questionnaire object in a for-each loop
    public Iterator<Question> iterator() { return questions.iterator(); }

    @Override
    public String toString() { return questions.toString(); }
}

You could add many more goodies to your class to make it more useful. An example of using the class above follows:

public class QuestionnaireTest {
    public static void main(String[] words) {
        Questionnaire questionnaire = new Questionnaire(words);
        for(Question q : questionnaire) {
            System.out.println("You asked: " + q);
        }
    }
}

You could also use it as follows:

public class QuestionnaireTest3 {
    public static void main(String[] words) {

        // because I declared the constructor to accept "String ...words", I can specify as many questions as I want using simple syntax
        Questionnaire questionnaire = new Questionnaire("How deep the ocean?", "How high the moon?");
        for(Question q : questionnaire) {
            System.out.println("I asked: " + q);
        }
    }
}

Even though I did so in my first example above, you should really accept an array of String objects as questions. Here's a better design:

public class Questionnaire implements Iterable<Question> {
    private List<Question> questions = new ArrayList<Question>();

    public void add(Question q) {
        if(q == null) throw new IllegalArgumentException("can't add null question!");

        questions.add(q);
    }

    public Question get(int index) {
       if(index < 0 || index >= questions.size()) throw new IndexOutOfBoundsException("invalid question index: " + index);

       return questions.get(index);
    }

    // allows you to use a Questionnaire object in a for-each loop
    public Iterator<Question> iterator() { 
        return Collections.unmodifiableList(questions).iterator();
    }

    @Override
    public String toString() { return questions.toString(); }
}

public abstract class Question {
    public String getText();
    public String getAnswer();
    public String getOptions();
    // ...
}

public class YesNoQuestion extends Question {
    private final String text;
    private final String answer;

    public YesNoQuestion(String text, boolean answer) {
       if(!(text.startsWith("Is"))) throw new IllegalArgumentException("Must start with is: " + text);

        this.text = text;

        this.answer = answer ? "Yes" : "No"; // if answer == true, the "Yes",...
    }

     @Override
     public String getText() { return text; }

     public String getAnswer() { return answer; }

     public String getOptions() { return "Yes or No ?"; }
}

And now you can use it as follows:

public class QuestionnaireTest4 {
    public static void main(String[] words) {

        Questionnaire test = new Questionnaire();

        test.add(new YesNoQuestion("Is dogs animals?", false));
        test.add(new YesNoQuestion("Is me has cheezburgers?", true));

        for(Question q : questionnaire) {

            System.out.println(q);
            System.out.println(q.getOptions());

            String input = null; // you need to code this part
            if(q.getAnswer().equals(input))
                System.out.println("CORRECT!");
            else
                System.out.println("YOU IS STUPID!!!!");
        }
    }
}

2 Comments

Are you talking about {get; set;} on my post and you are showing him an ITERATOR??? COME ON!!!
LMAO!!!!! Hey - that Iterator trick can make your life more pleasant. It's nice to be able to think about something that is a collection of things as a collection. This way you don't need to actually expose your List to clients. Just give them an add, get method and the Iteratate method. Maybe a numberOfQuestions() too. I'm assuming that the person is going to actually want to build a program with his class. I think I was complaining about non-java code as an answer to a Java question!!!!

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.