【问题标题】:is there a way to access an object within an object?有没有办法访问对象中的对象?
【发布时间】:2016-03-31 07:38:23
【问题描述】:

我正在通过构建一个简单的目录来练习 java。我有 4 节课。它们是:

  1. 地址

  2. 联系方式

  3. testClass

我已经完成了这个系统的创建,它可以按照我想要的方式工作。我通过为 Person、Address 和 Contact 创建 3 个不同的数组来做到这一点。要将人员、地址和联系人链接在一起,我将它们放在具有相同索引号的相应数组中。 (不是字面上将它们联系在一起,只是一种在编辑人员时知道要访问哪个地址或联系人的方法。

但是现在,我想优化它。我想创建一个 HashMap 来保存一个人,其中包含地址和联系人。请参阅下面的代码以获取更多信息。

Person.class

public class Person {
private long Id;
private firtName;
private Address address;
private Contact contact;

//some setter and getter methods

public Person(Address address, Contact contact) {
this.address = address;
this.contact = contact;
}
}

地址.class

public class Address {

private String street;
private String city;
private String province;


//some setter and getter methods
}

联系人.class

public class Contact {

private long Phone;
private String Email;

//some setter and getter methods
}

testClass.class

public class testClass {

public static void main(String[] args) {
HashMap<Integer, Person> person = new HashMap<Integer, Person>();

person.put(1, new Person(new Address(), new Contact)));
person.get(1).setStreet("place");

}

}

我的问题是,在 testClass 中的这行代码

person.get(1).setStreet("place");

有没有一种方法可以直接访问/编辑人员的地址或联系人,而无需创建单独的数组或方法?

【问题讨论】:

  • 我不明白这里有什么问题。什么是“直接访问”,你说的是什么数组/方法?
  • 拥有地址和联系人的getter方法并修改它们。
  • 对您的命名稍作补充。联系人可能会被误认为是人,而您的意思是联系信息。并且将一组人称为单数也令人困惑。阅读为 indexedPeople 或 peopleMap 或至少只是 people 会更容易。

标签: java hashmap composition


【解决方案1】:
private Address address;
private Contact contact;

如果您要创建这些 public 而不是 private,您将能够像这样直接访问它们:

Person person = new Person(new Address(), new Contact());

Person p = person.get(1);
String city = p.address.getCity();
String email = p.contact.getEmail();

但是这违反了封装原则(你应该隐藏你的内部字段并且只允许通过方法访问)。

相反,您应该按如下方式创建您的人员类:

public class Person {
    private long Id;
    private firtName;
    private Address address;
    private Contact contact;

//some setter and getter methods

    public Person(Address address, Contact contact) {
        this.address = address;
        this.contact = contact;
    }

    public Address getAddress() {
        return address;
    }

    public Contact getContact() {
        return contact;
    }
}

并通过

Person p = person.get(1);
String city = p.getAddress().getCity();
String email = p.getContact().getEmail();

【讨论】:

  • 通过创建方法 getAddress() 和 getContact() 意味着我正在创建这两个类的实例,对吗?但是如果我必须制作 100 个人,我还需要为每个 getAddress 和 getContact 制作 100 个引用吗?我不知道这是否会是一个好的设计。
  • 只有在使用“new”关键字时才创建这些类的实例。之后,您的 Person 类将对其位置的引用保存在内存中,而 getAddress 只是返回相同的对象。
  • 对此的小补充:您不一定需要在构造函数中传递地址和联系信息。您还可以为这些创建设置器。但这在很大程度上取决于您的业务逻辑。
  • 我终于明白这背后的逻辑了。谢谢你的帮助!我终于能够按照我想要的方式运行它了。
【解决方案2】:

当一个人是地址、联系信息等的集合体时,你应该有这些的 getter 和 setter。然后你会写这个来设置一个人的街道:

person.getAddress().setStreet("this and that")

你也可以分配一个新地址:

person.setAddress(new Address("streeetname", "cityname"))

这是 Java 中的一个常见习语,也是要走的路。拥有公共访问对象会产生新的问题,因为这种访问不能在所有使用它们的类中没有副作用的情况下更改。

【讨论】:

  • 我对这种方法的问题是我需要为一个人的每个 getAddress 进行引用的数量。我想不出如何使用前缀自动创建对象以使这些引用不同的解决方案。
  • 对不起,我不太明白这里的问题
  • 现在我明白了。这是关于我使用 person 而不是 person.get(x),对吗?在我的示例中,person 对象是 Person 的一个实例。请参阅我对有关命名约定的问题的评论。
【解决方案3】:

我在这里看到的是依赖倒置问题。您的课程 Person 取决于 AddressContact。从最纯粹的意义上讲,地址和联系人应该是接口,因此它们的实现可以在运行时换出。

public class Person {
  private long Id;
  private firstName;
  private Address address;
  private Contact contact;

  public Person(Address address, Contact contact) {
    this.address = address;
    this.contact = contact;
  }

  public Address getAddress() {
    return this.address;
  }

  public setAddress(Address address) {
    this.address = address;
  }

  public Contact getContact() {
    return this.contact;
  }

  public setContact(Contact contact) {
    this.contact = contact;
  }

}

那么你可以通过以下方式访问Address

person.get(1).getAddress().setStreet("place");

【讨论】:

    猜你喜欢
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2011-01-23
    • 1970-01-01
    • 2021-10-11
    • 2021-05-30
    相关资源
    最近更新 更多