【问题标题】:Storing two types of objects in an ArrayList in Java在 Java 的 ArrayList 中存储两种类型的对象
【发布时间】:2017-11-13 01:01:13
【问题描述】:

我正在做一个学校项目,我需要创建一个 ArrayList 包含两种类型的对象,“经理”和“售票员”,因为我创建了一个抽象类“用户”并且这两种类型扩展了它,我已经创建了一个 ArrayList 类型“user”并在其中存储了“managers”和“ticket salesmen”,但是如何访问这两种类型呢?我只能以“用户”的身份访问列表的每个元素,并获取抽象类所具有的属性,而不是“经理”或“售票员”。如何获取这两个对象的属性,我能否识别对象类型,比如它是哪个类的实例?

【问题讨论】:

  • 贴实际代码比贴描述好很多
  • 我想说问一下初学者,你为什么要把这两种类型放在一起?他们有什么共同点?
  • 请点击以下链接获取此解决方案:stackoverflow.com/a/34437757/3095589
  • @Antoniossss 我将它们放在一起,因为作业文本是这样说的,如果我改变一些东西,我会失去积分
  • @MilosRasevic 听起来像是无用的分配

标签: java eclipse class arraylist abstract


【解决方案1】:

您可以使用instanceof 运算符来识别用户的实际类型

User obj = new Manager();
User obj2 = new SalesMan();
System.out.println(obj instanceof Manager); // true
System.out.println(obj instanceof SalesMan);// false

System.out.println(obj2 instanceof Manager); // false
System.out.println(obj2 instanceof SalesMan);// true

【讨论】:

  • ...但大多数情况下,只有在应用程序设计不佳时才需要强制转换。
  • 我同意。如果可能,应避免使用 instanceOf。
  • @HenryMaathuis 为什么要避免使用 instanceof?
  • 这通常并不总是很糟糕,但如果有人提前知道,这是可以避免的,read more about it here
【解决方案2】:

您应该首先检查子类的类型。这可以通过使用 instanceOf 运算符来完成。一旦确定了子类类型,就应该将 User 强制转换为该特定子类。转换后,您可以访问该特定子类的功能。

但请注意,应尽可能避免使用 instanceOf。为避免使用 instanceOf,您可以查看此 question 上接受的答案。

【讨论】:

  • 这不是“一般不好的做法” - 所以你的陈述是错误的。在给定的上下文中使用它是不好的,但不是一般的。
  • 我概括的有点过头了。在某些情况下它可能有用,但实际上在给定的上下文中它是可以避免的。
【解决方案3】:

遍历arrayList,使用instanceof检查类型,然后转换为使用方法和属性。试试这样的。

for (User user : arrayList) {
    if (user instanceof Manager) {
        Manager manager = (Manager) user;
        //manager.method();
    } else if(list instanceof SalesMan){
        SalesMan salesMan = (SalesMan) user;
        //salesMan.method();
    }     
}

【讨论】:

    【解决方案4】:

    另一种方法是使用getClass() 获取类的类型:

    for (Object obj : userArrayList) {
        if (obj.getClass().equals(Manager.class)) {
          ...
        }
        if (obj.getClass().equals(Salesman.class)) {
          ...
        }
    }
    

    还应注意,instanceof 在子类的情况下也可以工作,但这样就不行了。

    【讨论】:

      【解决方案5】:

      请按照以下链接获取解决方案:

      https://stackoverflow.com/a/34437757/3095589

      或许对你有帮助……

      【讨论】:

        【解决方案6】:

        虽然其他答案完美地描述了如何实现您所要求的,但由于各种原因,您寻求做的通常被认为是面向对象设计中的不好的做法

        1. 耦合:当您的代码根据对象的类型做出决定时,您必须在添加更多类型时添加更多条件检查,即第三个User 类型。这很糟糕,因为它使维护代码变得更加困难。添加其他子类时,您必须找到代码中可能需要特殊行为的所有位置。忘记对提到的任何一个地方执行此操作,您的代码就会中断。
        2. 使用 instanceof 意味着您需要以不同的方式处理超类的不同子类;所以超类可能没有足够的共享功能/数据首先成为超类?如果它们的特征如此之少,为什么要将它们存储在一起?

        考虑重新设计您的代码。如果您仍然认为 ManagerTicketSalesMan 必须继承自 User,并且需要在迭代循环中对它们执行一些操作,请考虑 覆盖一个方法而不是使用instanceof。看下面的代码:

        public abstract class User
        {
            public abstract void doOperation();
        }
        
        public class Manager extends User
        {
            public void doOperation()
            {
                // do stuff that managers do
            }
        }
        
        public class SalesMan extends User
        {
            public void doOperation()
            {
                // do stuff that salesmen do
            }
        }
        
        public class Main
        {
            public static final void main(String[] args)
            {
                ArrayList<User> users = getUsers();
                for(User u: users)
                {
                    u.doOperation();
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-19
          • 1970-01-01
          • 2018-07-20
          • 2013-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-10
          相关资源
          最近更新 更多