在一个 collection 的 superclass 中循环不同的 objects (扩展了普通的 super class)

looping over different objects (that extends common super class) in one collection of superclasses

我在 java 中与继承作斗争。我有许多具有相似属性的元素,例如 f.e。 idnamedate。该元素还指定了只属于它们的参数,例如:emailaddress.

我想在 collection 中保留这些不同的元素。然后使用循环在控制台中显示它们。但是当我放置像 email 这样的元素时(这是为具体的 class User 指定的)它给了我一个错误:

value email is not a member of Person

代码如下:

public class Person {
  int id;
  String name;
  Date date;
}
public class User extends Person {
  String email;
  String login;
  String password;
}
public class Contact extends Person {
  Address address;
}

public class Customer {
  List<Person> persons;

  // AND NOW I WOULD LIKE TO PRINT THIS
  public void print() {
    for(Person person: this.persons) {
      System.out.println(person.id + " " + person.email);
    }
  }
}

我在 Java 中有很多类似的继承问题。我不知道如何继续下去?如何实现 classes,我可以让它工作。

你能给我一些好的Design Pattern或线索吗?

我正在寻找一些先进的东西,这将使我能够处理仅在扩展 classes 中出现的参数。我想通过参数名称调用它们。 我已经尝试为每个扩展 class 实现打印方法,但它是通用的。我必须有权访问参数。

你的具体例子很容易解决。为了打印 class 的对象,覆盖 class.

的 toString

然后你的打印方法变成:

  public void print() {
    for(Person person: this.persons) {
      System.out.println (person);
    }
  }

每个 class 都知道它的字符串表示应该是什么样子。例如,在用户 class :

public class User extends Person
{
    @Override
    String toString ()
    {
        return this.id + " " + this.email;
    }
}

编辑:

如果您希望从类型为超级 class 的变量访问子 class 的成员(例如从 Person 变量访问电子邮件 属性 ),您必须首先将变量转换为子 class 的类型(在您的示例中为 User),并确保此转换有效(例如,通过使用 instanceof 来验证person instanceof User)。

有时无法避免此类转换,但转换过多通常表明您的设计存在缺陷。处理人员集合时,应避免访问仅在某些子 class 中定义的特定属性。您应该尝试只调用 Person class 的方法,并且可以在子 class 中覆盖这些方法以提供不同的行为。

在编程中,您很少能做到一刀切。 IMO 甚至没有设计模式。在你的情况下,我会做类似的事情:

for(Person person: this.persons) {
   if (person typeof User) 
      System.out.println(person.id + " " + ((User)person).email);
}

希望其他人能想出更奇特的东西 :-)

很简单。 email 是 User 的成员,不是 Person.So 你不能编译这段代码。

从用户中删除电子邮件并将其添加到人员 class。

让我们看看您的代码。 您的 Collection 可以拥有扩展 Person 本身的所有 class 个中的 Objects 个。 这意味着,可能有一些 Objects 的 Person,一些 User 等等。 Collection 本身不能真正确定它包含某个 Class 的哪个 Objects。 我们可以看到您的 Superclass Person 没有属性 email。只有 class 用户拥有(以及所有可能从其延伸的 classes)。因此,在 Superclass Person 的对象上,您将无法从属性 "email" 接收数据,仅仅是因为它没有该成员。 基本类型 Person 的 Collection 无法访问属性电子邮件,即使它可能在子classes 中可用,因为无法确保调用不会在所有 [=36] 上失败=] 可以放入 collection.

可能有哪些解决方法:

  • 最简单,不要尝试访问在 collection
  • 的基本类型
  • 如上所述,在classes中定义toString()方法。 然后就可以在Objects中看到会员邮箱的值了 Class 用户。
  • 如果您知道您的 collection 本身将只有用户 Objects, 只需更改 bastype
  • ClassX instanceof ClassY returns 真假取决于是否 ClassX 是 ClassY 的子class。所以你可以把它放在一个 if 语句中。如果某些东西是用户的实例,那么您可以毫无问题地访问成员电子邮件。不过记得在 if-statement 的正文中转换为 User。