【问题标题】:Multiple object types in one ArrayList一个 ArrayList 中的多种对象类型
【发布时间】:2014-04-10 13:01:26
【问题描述】:

我有一个名为 User 的抽象类,用户可以创建为 Student 类型或 Teacher 类型。我已经创建了一个用户(学生和教师)的 ArrayList,我想做的是根据当前对象的实例调用一个方法示例:

for (User user : listOfUsers) {

  String name = user.getName();

  if (user instanceof Student) {

    // call getGrade();

  } else { // it is an instance of a Teacher

    // call getSubject();
  }
}

我遇到的问题是因为它是User对象的ArrayList,它无法获取Student类型的方法,例如getGrade()。但是,因为我能够确定当前用户的实例,所以我很好奇是否仍然可以根据用户类型调用特定方法。

这可能吗,还是我必须将用户类型分成单独的列表?

请尽快回复,非常感谢。

【问题讨论】:

    标签: java arraylist abstract-class abstract instanceof


    【解决方案1】:

    在使用该方法之前,您需要将它们强制转换为类。

    for (User user : listOfUsers) {
    
        String name = user.getName();
    
        if (user instanceof Student) {
    
            Student tmp = (Student)user;
    
            // call getGrade();
            tmp.getGrade();
    
        } else { // it is an instance of a Teacher
            Teacher tmp = (Teacher)user;
            // call getSubject();
            tmp.getSubject();
        }
    }
    

    【讨论】:

      【解决方案2】:

      查看downcast:

      在面向对象的编程中,向下转换或类型细化是 将基类的引用转换为其派生类之一的行为 类。

      在许多编程语言中,可以通过类型检查 内省判断被引用对象的类型 确实是被强制转换的类型或它的派生类型,因此 如果不是这种情况,则发出错误。

      也就是说,当基类(父类)的一个变量有一个 派生类(子类)的值,可以向下转换。

      将您的代码更改为:

      if (user instanceof Student) {
      
          ((Student) user).getGrade();
      
        } else { // it is an instance of a Teacher
      
          ((Teacher) user).getSubject();
        }
      

      【讨论】:

      • 很好的答案。链接、定义和示例。虽然也许你应该做其他 if (user instanceof Teacher) {} 并在底部放一个 else 只是为了默认行为
      • Tnx @Nappa 赛亚人!
      • 抱歉回复晚了,我的电脑请求重新启动以进行一些更新。感谢您的及时回复,这确实有效,非常感谢。
      【解决方案3】:

      将学生和教师对象存储在 userList 中,然后根据 instanceOf 条件通过 typeCasting 到 UserType 调用相应的类方法

      考虑下面的示例代码

         abstract class User{
      
              public abstract String getName();
          }
      
          class Student extends User{
      
              @Override
              public String getName() {
                  // TODO Auto-generated method stub
                  return "Student";
              }
      
              public String getGrade(){
                  return "First Class";
              }
      
          }
      
      
          class Teacher extends User{
      
              @Override
              public String getName() {
                  // TODO Auto-generated method stub
                  return "Teacher";
              }
      
              public String getSubject(){
                  return "Java";
              }
      
          }
      
      public class  Util {
      
      public static void main(String[] args) {
      
      
              Student s = new Student();
              Teacher t = new Teacher();
      
              ArrayList<User> list = new ArrayList<User>();
              list.add(s);
              list.add(t);
      
              for(User user :list){
                  if(user instanceof Student){
                      System.out.println(((Student) user).getGrade());
                  }
      
                  if(user instanceof Teacher){
                      System.out.println(((Teacher) user).getSubject());
                  }
              }
      }
      }
      

      【讨论】:

      • 应该是这个样子。此外,方法 getSubject 和 getGrade 应该作为 getInfo 或类似的东西移到超类中。这将避免 if 子句和 instanceof
      • 是的,这是可能的……但是 inheritance 功能说子类从父类获取特性,另外它可以有自己的特性。在上面的示例中,学生可以有 getBranch()、getLastYearMarks() 等方法,而教师可以有 getQualification() 等。在这些情况下,我们仍然需要 if 条件来调用特定方法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2015-11-10
      • 2011-11-16
      • 2022-06-15
      • 2017-11-13
      • 1970-01-01
      相关资源
      最近更新 更多