在一个超类集合中循环遍历不同的对象(扩展了常见的超类)

时间:2015-06-01 10:42:42

标签: java inheritance design-patterns

我在java中继承困难。我有许多具有类似属性的元素,如f.e. idnamedate。此元素还指定了仅属于它们的参数,例如:emailaddress

我想在收集中保留这些不同的元素。然后使用循环在控制台中显示它们。但是当我放置像email这样的元素(为具体类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中有很多类似的继承问题。我不知道如何继续使用它?如何实现类,我可以使它工作。

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

我正在寻找一些先进的东西,这将允许我使用仅在扩展类中出现的参数。我想通过参数名称来调用它们。 我已经尝试过为每个扩展类实现print方法,但它是一般的。我必须能够访问参数。

4 个答案:

答案 0 :(得分:3)

您的具体示例很容易解决。要打印类的对象,请覆盖该类的toString。

然后您的打印方法变为:

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

每个类都知道它的String表示应该是什么样子。例如,在User类中:

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

编辑:

如果您希望从类型为超类的变量访问子类的成员(例如,从Person变量访问email属性),则必须首先将变量强制转换为子类的类型-class(示例中为User),并确保此强制转换有效(例如,使用instanceof验证person instanceof User)。

有时无法避免这样的演员阵容,但过多的演员经常暗示你的设计存在缺陷。处理人员集合时,应避免访问仅在某些子类中定义的特定属性。您应该尝试仅调用Person类的方法,并且可以在子类中重写这些方法以提供不同的行为。

答案 1 :(得分:1)

让我们来看看你的代码。 您的集合可以包含所有类的对象,这些类本身可以扩展Person。 这意味着,可能存在一些Person对象,一些User等等。 Collection本身无法确定它包含的某个类的哪些对象。 我们可以看到您的超级人员没有属性电子邮件。只有User类(以及可能从中扩展的所有类)。因此,在Superclass Person的Obejct上,您将无法从属性&#34; email&#34;中接收数据。仅仅因为它没有那个成员。 基本类型人员的集合无法访问属性电子邮件,即使它可能在子类中可用,因为无法确保调用不会在可能放入集合的所有对象上失败。

可能有哪些变通方法:

  • 最简单,不要试图访问一个不可用的成员 集合的基本类型
  • 如上所述,在类中定义toString()方法。 然后你可以在对象中看到成员电子邮件的价值 班级用户。
  • 如果你知道你的收藏品本身只有用户对象, 只需更改bastype
  • ClassX instanceof ClassY返回true为false,具体取决于是否ClassX是ClassY的子类。所以你可以把它放在if语句中。如果某个用户是某个用户的实例,那么您可以毫无问题地访问该成员电子邮件。记得在if语句的主体中强制转换为User。

答案 2 :(得分:0)

在编程中,你很少有一种尺寸适合所有。 IMO甚至没有设计模式。在你的情况下,我会做类似的事情:

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

希望别人可以找到更高级的东西:-)

答案 3 :(得分:-1)

这很简单。 email是User not Person的成员。因此您无法编译此代码。

从用户删除电子邮件并将其添加到Person类。