【问题标题】:How to fill a list with similar but different objects?如何用相似但不同的对象填充列表?
【发布时间】:2014-07-01 20:14:26
【问题描述】:

我有两个类可以说是“QuestionOne”和“QuestionsTwo”,它们非常相似并且继承自基类“Question”。现在我想编写一个用任一类的对象填充 ArrayList 的方法。

public ArrayList<QuestionOne> list = new ArrayList<QuestionOne>();

public void fill(QuestionOne questionOne){
list.add(questionOne);
}

这将是一种填充 QuestionOne 对象的方法。但我希望该方法能够用“QuestionOne”和“QuestionTwo”两种类型的对象填充列表。

我想补充什么...我想使用“questionOne”和“questionTwo”的所有方法。

我怎样才能做到这一点?我需要一个接口吗?我不知道...

【问题讨论】:

  • 在您的代码中将QuestionOne 替换为Question
  • 这两个类有什么共同点?
  • 一种方法是:ArrayList list = new ArrayList ();
  • 你能只调用基类Question中的方法吗?还是您需要调用特定于每个类的方法?

标签: java class inheritance interface


【解决方案1】:
public ArrayList<Question> list = new ArrayList<Question>();

现在,只要xQuestionQuestion 的子类的任何对象,list.add(x) 就可以工作。

一般来说,只要您说变量或参数的类型为C,它就可以包含对CC 的任何子类的引用。这同样适用于 ArrayList add 例程的参数,如下所示:

boolean add(Question e) 

因此,您可以将任何 Question 的子类添加到您的列表中。

P.S.: 一些 cmets 也建议更改 fill 的参数。你可以这样做,但你不必这样做。这取决于您的要求。这仍然有效:

public void fill(QuestionOne questionOne){
    list.add(questionOne);
}

因为questionOneQuestion(同时也是QuestionOne)。如果你真的需要,你可以重载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);
    }
}

通常最好通过向Question 添加一个在QuestionOneQuestionTwo 中覆盖的多态方法来执行此类操作。但这并不总是可能的。我只是提出这一点来指出fill 的参数实际上并不需要更改,尽管您可能想要。

【讨论】:

    【解决方案2】:

    如前所述,您可以创建一个 Question 类型的 ArrayList。这意味着您将只能使用在 Question 类中定义的方法。

    例如

    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"
        }
    
    }
    

    【讨论】:

    • 这是个大问题。现在我不能使用 questions.get(0).doSomethingElse()。但这正是我想要的^^
    • 您能解释一下 QuestionOne 需要做什么,而 QuestionTwo 不需要吗? (反之亦然)谢谢
    • 请注意,一般情况下,instanceof 关键字只能作为最后的手段使用。覆盖方法通常是可取的。更多信息请访问javapractices.com/topic/TopicAction.do?Id=31
    【解决方案3】:

    如果您使用抽象类Question,您将能够使用Question 的arraylist 来存储两个子类对象。

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

    要回溯,可以使用instanceof进行比较:

    { //...
      for(final Question element:list){
        if(element instanceof QuestionOne){
          QuestionOne question=(QuestionOne)element;
          // Use it here.
        }
        //...
      }
    }
    

    【讨论】:

      【解决方案4】:

      创建一个ArrayList&lt;Question&gt; 并以这种方式填写。虽然您只有可用的接口,但 Question 类公开。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-25
        • 2021-04-19
        • 1970-01-01
        • 2013-04-21
        • 1970-01-01
        相关资源
        最近更新 更多