I have two classes lets say "QuestionOne" and "QuestionsTwo" which are very similar and inherit from a Baseclass "Question". Now I want to write a method which fills a ArrayList with Objects of either class.
public ArrayList<QuestionOne> list = new ArrayList<QuestionOne>();
public void fill(QuestionOne questionOne){
list.add(questionOne);
}
That would be a method to fill QuestionOne objects. But I want the method to be able to fill the list with both type of objects "QuestionOne" and "QuestionTwo".
What I would like to add...I want to use alle methods of "questionOne" and "questionTwo".
How can I achieve this? Do I need an Interface? I don't know...
Make an ArrayList<Question>
and fill it up that way. Although you'll only have the interface available, that the Question class exposes.
If you use an abstract class Question
, you will be able to use an arraylist of Question
to store both subclass objects.
class Question{}
class QuestionOne extends Question{}
class QuestionTwo extends Question{}
ArrayList<Question> list = new ArrayList<Question>();
// This method will take any subclass of Question.
public void fill(Question question){
list.add(question);
}
To backcast, you can use instanceof
to compare:
{ //...
for(final Question element:list){
if(element instanceof QuestionOne){
QuestionOne question=(QuestionOne)element;
// Use it here.
}
//...
}
}
public ArrayList<Question> list = new ArrayList<Question>();
Now list.add(x)
will work whenever x
is a Question
or any object of a subclass of Question
.
In general, any time you say that a variable or parameter has type C
, it can contain a reference to a C
or any subclass of C
. This applies just as well to the parameter of the ArrayList
add
routine, which will look like this:
boolean add(Question e)
So you can add anything that is a subclass of Question
to your list.
Some comments are suggesting changing the parameter of fill
also. 一些评论建议也更改fill
参数。 You can do that, but you don't have to. It depends on your requirements. This will still work:
public void fill(QuestionOne questionOne){
list.add(questionOne);
}
since questionOne
is a Question
(as well as being a QuestionOne
). If you really need to, you could overload fill
:
public void fill(QuestionOne questionOne){
System.out.println("I'm adding a Type I question");
list.add(questionOne);
}
public void fill(QuestionTwo questionTwo){
if (questionTwo.isInteresting()) {
// assume isInteresting is a method that is defined only for QuestionTwo
System.out.println("I'm adding a Type II question");
list.add(questionTwo);
}
}
Usually it would be better to do something like this by adding a polymorphic method to Question
that is overridden in QuestionOne
and QuestionTwo
. But this isn't always possible. I'm just bringing this up to point out that the parameter of fill
doesn't actually need to change, although you might want to.
As mentioned, you can create an ArrayList of type Question. This means that you will only be able to use methods that are defined in the Question class.
For example
public class Question {
public void askAQuestion(){
System.out.println("Im asking a question");
}
}
_
public class QuestionOne extends Question {
@Override
public void askAQuestion(){
// You can override a method. As long as it has the same name and
// return type, it can have it's own functionality
System.out.println("Im asking question one");
}
public void doSomethingElse(){
// Because this method is not in the Question class, you cannot use
// it in your ArrayList
}
}
_
public class QuestionTwo {
@Override
public void askAQuestion(){
System.out.println("Im asking question two");
}
}
_
public class MainClass {
public static void main (String[] args){
List<Question> questions = new ArrayList<Question>();
questions.add(new QuestionOne());
questions.add(new QuestionTwo());
questions.get(0).askAQuestion(); // Outputs "Im asking question one"
questions.get(1).askAQuestion(); // Outputs "Im asking question two"
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.