在 Java 中的 ArrayList 中存储两种类型的对象

Storing two types of objects in an ArrayList in Java

我正在做一个学校项目,我需要创建一个包含两种类型对象的 ArrayList,"managers" 和 "ticket salesmen",因为我创建了一个抽象 class "user" 和这两种类型扩展它,我创建了一个 ArrayList 类型 "user" 并在其中存储了 "managers" 和 "ticket salesmen",但是如何访问这两种类型?我只能作为 "user" 访问列表的每个元素,并获取抽象 class 具有的属性,而不是 "manager" 或 "ticket salesman"。如何获取属性这两个对象,我可以识别对象类型吗,其中 class 是它的一个实例吗?

您可以使用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 运算符来完成。一旦确定了子类类型,就应该将 User 转换为该特定子类。转换后,您可以访问该特定子类的功能。

但是请注意,应尽可能避免使用 instanceOf。为避免使用 instanceOf,您可以查看此 question.

上已接受的答案

遍历 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();
    }     
}

另一种方法是使用 getClass():

获取 class 的类型
for (Object obj : userArrayList) {
    if (obj.getClass().equals(Manager.class)) {
      ...
    }
    if (obj.getClass().equals(Salesman.class)) {
      ...
    }
}

还应注意,instanceof 也适用于 subclasses,但这样就不行了。

请按照以下 link 找到您的解决方案:

说不定对你有帮助...

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

  1. 耦合:当您的代码根据对象的类型做出决定时,无论何时添加更多类型,即第三种 User 类型,您都必须添加更多条件检查。这很糟糕,因为它使维护代码的难度成倍增加。当您添加额外的子类时,您将不得不找到代码中所有可能需要特殊行为的地方。忘记为提到的地方之一执行此操作,并且您的代码会中断。
  2. 使用instanceof意味着你需要以不同的方式对待超类的不同子类;所以那个超类可能没有足够的共享 functionality/data 首先成为超类?如果它们共享的特征如此之少,为什么要将它们存储在一起?

考虑重新设计您的代码。如果你仍然认为 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();
        }
    }
}