【问题标题】:Call methods from a class that is inside an array从数组内的类调用方法
【发布时间】:2013-01-22 09:28:30
【问题描述】:

我有一个里面有对象的数组。如何在数组元素上使用方法?

我的数组是Object 类型。我试过array[i].getSalary(),但这不起作用。

【问题讨论】:

  • 你可以施放它,但我求你不要施放。不要将您的数组设为 Object 类型,而是将其设为泛型。
  • +1。解决方案是使您的数组不是类型为Object[],而是类型为Employee[] 或其他类型。
  • 那么你只能在转换后调用像 getSalary() 这样的方法,这是一种 HORRIBLE 方法。也许你误解了你的教授,并且可以使用任何非原始的对象。例如,如果您有一个名为 Employee 的类,那么 Employee 的所有实例都是对象。
  • 你的教授不太懂Java...
  • @jahroy 他们的教授可能会强迫他们先使用可怕的版本,然后再向他们展示优雅的版本,让他们通过动手比较了解它的价值。我不是说这就是正在发生的事情,我说这是一种可能性。

标签: java arrays object methods


【解决方案1】:

首先,您几乎不应该使用Object 的数组。原因是您丢失了所有类型信息:

  • 将使那些将阅读您的代码的人(包括您的教授、您自己以及六个月后您将忘记有关代码的所有内容的您自己)更容易理解代码
  • 甚至在您测试程序之前,编译器和您的 IDE 都可以使用它来告诉您何时出错。
  • 将避免我将在此答案的第二部分向您解释的容易出错的类型转换。

不要使用Object 的数组,而是使用与将放入其中的对象(或公共基类)的类型相对应的类型的数组。假设你的类被称为Employee,你应该这样声明你的数组:

Employee[] employeeArray;

employeeArray 是一个比 array 更好的名称,因为它说明了它包含什么类型的对象,同样是为了便于阅读。通常,变量更喜欢显式名称。)

如果Employee 类包含这样的方法,则使用该解决方案很容易使用employeeArray[i].getSalary()。这段代码的用意,读起来也一目了然。

其他可能性是通用集合,例如 List<Employee>Set<Employee>,具体取决于您的需要。

如果你真的必须使用 Object 数组,并调用 getSalary() 方法,你将不得不将数组元素转换到类或接口以getSalary() 方法属于哪个。

再比如,如果这个类被称为Employee

Employee employee = (Employee) array[i];
employee.getSalary();

casting 所做的是获取对象的 Employee 类型的引用。对象还是一样的,但是现在你可以在这个对象上调用Employee的方法了。

但是这个解决方案有很多注意事项。首先,它更冗长,需要两行才能完成本来可以只写一行的内容。其次,更重要的是,由于你有一个Object 的数组,你不能确定你真的有一个Employee 类型的对象,如果不是这样,操作会抛出一个ClassCastException。解决这个问题的方法是首先检查对象是否真的是所需的类型:

Object object = array[i];
if (object instanceof Employee) {
    Employee employee = (Employee) object;
    employee.getSalary();
}
else {
    System.err.println("Object is not an Employee: we can not call getSalary()!");
}

但是您会发现它变得更加冗长,如果将其乘以必须调用这些对象的方法的次数,那么代码将变得难以管理。

【讨论】:

  • 我希望一个拥有 >2000 代表的用户提出一个涉及泛型的更好的解决方案,而不是一个糟糕的解决方案,至少你应该解释这种解决方案的问题或拥有一个 Object 类型的数组. OP 可以使用除员工以外的类型数组,并且仍然可以使用泛型。
  • 我明白你的意思,但首先,由于这个建议已经在 cmets 中给出,我觉得没有必要马上重复。其次,即使OP的问题的前提很糟糕,他的问题仍然表明缺乏关于演员的知识,所以我认为向他展示这种事情是可能的并不是一件坏事。但是感谢您的评论,我将修改我的答案。
  • 问题不在于OP,其他人会看到这个答案并学习一个不好的做法。显式转换是应该尽可能避免的事情,它会在运行时引入问题,这些问题可能会在编译时被捕获,从而否定了 java 被强类型化的好处。这在逻辑上也毫无意义,“看到我告诉你的那个对象是'对象'类型的吗?我撒谎了,它实际上是一个'员工'”。这类问题正是对 java 泛型的解释可以方便地帮助 OP 学习和未来用户在相同情况下。
  • @Benjamin Gruenbaum 我完全同意你的观点,OP 应该了解为什么这是一种糟糕的 Java 方法。但是,如果他的教授要求数组是 Object 类型,那么 Cyrille Karmann 确实给出了正确答案。我并不是说应该这样做,这是对 Java 的一种糟糕使用,但鉴于他必须使用 Object 数组,我没有看到更好的方法。
  • @sage88 在这种情况下,答案应该是“你应该做这个和那个(制作 Employee 类型的数组,使用带有 extends Employee> 的泛型和其他想法),在极少数情况下你不能正确地做到这一点,你可以作为最后的手段,但它会出现以下问题。问题是这个问题以后会被人们阅读,他们会学到一个不好的做法。
【解决方案2】:

object[] 中的所有对象都具有getSalary() 方法吗?

  • 如果不是,那么您显然可以看到为什么编译器不允许您这样做。如果您最终遇到这种情况,您的代码中的某处会发生一些有趣的事情。

  • 如果是,是完全相同的getSalary() 方法还是同一类层次结构中同一方法的多个动态绑定实现?

    • 如果两者都不是,您可能应该创建一个接口IHasSalary(我知道这个名字很蹩脚),让所有这些对象都实现该接口,然后将数组声明为IHasSalary[]

    • 如果是,找到它们最特殊的共同祖先,说它是类Employee,并将数组声明为Employee[]

【讨论】:

  • 没有什么奇怪的事情发生。类 Object 没有方法 getSalary()。它必须被强制转换才能有适当的方法。我同意创建一个 Employee 数组会更好。
  • @sage88 我在那句话中的意思是代码的结构/逻辑有问题。这意味着如果你最终得到一个object[] 的对象,你知道这些对象属于某种更专业的类型,那么你在某处做了一些奇怪的事情。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2016-02-23
  • 2020-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多