如何在面向对象Java中建立两个对象之间的双向关联

如何在面向对象Java中建立两个对象之间的双向关联,java,class,oop,object,Java,Class,Oop,Object,我有一个基本的任务要做,但我对OOP非常陌生,并且正在努力解决它。其他在线资源开始增加我的困惑 我必须: 为班级成员编写代码。Person对象具有名称、年龄和地址等属性 为类狗编写代码。狗对象具有名称和年龄属性 在Person和Dog类中提供在Person对象和Dog对象之间建立双向关联所需的任何其他代码。人对象充当狗对象的所有者,狗对象充当人对象的宠物 修改Person类,使Person对象最多可以作为20个Dog对象的所有者 显然,这是一个非常简单的例子 我的代码到目前为止: 人员类别: 狗

我有一个基本的任务要做,但我对OOP非常陌生,并且正在努力解决它。其他在线资源开始增加我的困惑

我必须:

  • 为班级成员编写代码。Person对象具有名称、年龄和地址等属性

  • 为类狗编写代码。狗对象具有名称和年龄属性

  • 在Person和Dog类中提供在Person对象和Dog对象之间建立双向关联所需的任何其他代码。人对象充当狗对象的所有者,狗对象充当人对象的宠物

  • 修改Person类,使Person对象最多可以作为20个Dog对象的所有者

  • 显然,这是一个非常简单的例子

    我的代码到目前为止:

    人员类别:

    狗类:

    主要内容:

    我知道这段代码目前没有任何用处,但我不确定如何“关联”对象&在哪里做。分配规范指定一个人作为狗的“主人”


    这就是我的问题所在。设置对象之间的关系

    这是双向关系的常见问题;您不能在构造函数中传递它们,因为当初始化另一个时,其中一个还不存在。因此,您必须“从外部将其连接起来”

    你提到的20只狗表明他们希望你使用阵列来容纳狗,但是阵列列表会更好。我将使用arraylist,但如果您愿意,可以向您展示如何使用数组

    public class Person
        {
        ArrayList<Dog> dogs=new ArrayList<Dog>(); //this will hold all the dogs that the Person has as pets
    
        public void giveDog(Dog dog){
           dogs.add(dog)
        }
        .....
        .....
    
    使用这两种方法可以创建双向关系

    笔记
    这显然是一项任务,所以你除了未来别无选择;像这样的双向关系可能很有用。但如果使用不当,它们也很危险;最重要的是,在初始化之后,对象必须能够正常工作。它不能依赖于调用setOwner()或giveDog():换句话说,一个没有宠物的人和一只没有主人的狗必须行为“正确”(在这种情况下,这意味着什么。未能实现这一点可能会导致容易出现错误的代码。如果这是不正确的,那么没有主人的狗或没有狗的人肯定不可能接触到程序的其余部分;工厂方法对此很有用,但这超出了这个问题的范围e是一个问题。所以你能做的就是使用

    只需向类中添加第二种类型的实例变量:

    public class Person
    {
        private Dog myDog;
    
        private String name;
        private int age;
        private String address;
        ...etc.
    
    Dog
    类中,每只狗都有自己的主人:

    public class Dog
    {
        private Person myOwner;
    
        private String name;
        private int age;
    
    别忘了二传手和三传手

    关于第4点):

    4) 修改Person类,使Person对象最多可以作为20个Dog对象的所有者

    不要让每个
    对象都有一个
    成员,而是使用数组或某些集合(列表、集合等):

    所以不是

    private Dog myDog;
    

    private Dog[]dogArray=新狗[20];
    或
    私人收藏狗列表=新的ArrayList(20)//例如
    
    试试这个:

        Person person = new Person();
        Dog dog1 = new Dog();
        dog1.setAge(12);
    
        Dog dog2 = new Dog();
        dog2.setAge(34);
    
        person.addDog(dog1); //dog 1
        person.addDog(dog2); //dog 2
        person.listDogs(); //list of all dogs
    
    //人

    public class Person {
     // instance variables - replace the example below with your own
        private String name;
        private int age;
        private String address;
        private ArrayList<Dog> dogs = new ArrayList<Dog>();
    
    
    
        /**
         * Constructor for objects of class Person
         */
        public Person()
        {
           this.name = name;
           this.age = age;
           this.address = address;
        }
    
        public void addDog(Dog dog) {
            this.dogs.add(dog);
        }
    
        public void listDogs() {
            for(Dog item : this.dogs) {
                System.out.println(item.getAge());
            }
        }
    
    
    
        //Set Methods: 
        public void setName () {
                this.name = name;
        }
    
    
        public void setAge () {
                this.age = age;
        }
    
    
        public void setAddress () {
                this.address = address;
        }
    
    
        //Get Methods: 
        public String getName () {
                return name;
        }
    
        public int getAge () {
                return age;
        }
    
        public String getAddress () {
                return address;
        }
    }
    

    因为不能同时创建两个对象,所以不能在构造函数中相互传递引用。必须创建getter和setter方法,以便在创建对象后创建此关系。这方面的一个例子如下:

    public class Person
       Set<Dog> dogs = new HashSet<Dog>();
    
    
       public void addDog(Dog dog){
          if(dogs.size()>20){
               throw new IllegalArgumentException("exceeded the limit: ");         
          }  
          dogs.add(dog);    
       }
    }
    
    public class Dog
    {
        Person person;
    
        public void setPerson(Person person){
            this.person=person;
        }
    }
    
    公共类人物
    Set dogs=新HashSet();
    公狗{
    如果(dogs.size()>20){
    抛出新的IllegalArgumentException(“超出限制:”);
    }  
    狗。添加(狗);
    }
    }
    公家犬
    {
    个人;
    公众人士{
    这个人=人;
    }
    }
    
    这里的主要问题是一致性:如果狗d1是p1的宠物,那么p1必须是d1的主人,反之亦然。如果像许多人建议的那样,我们有两个方法(
    Person.addDog()
    Dog.setOwner()
    ),那么用户很容易犯错误,无法调用这两个方法(或者使用错误的参数调用)。由于狗只能有一个主人,一个简单而安全的界面将使用单个方法
    Dog.setOwner(Person p)
    ,如果我们希望狗没有主人,
    p
    可能为空。除了设置字段
    Dog.owner
    ,此方法还必须将此狗从以前主人的宠物列表中删除,并(如果p!=null)将其自身添加到新主人的宠物列表中。类
    Person
    添加和删除宠物的方法对于类
    Dog
    应该是可见的,但是对于用户来说不可见(它们应该是包私有的),而方法
    Dog.setOwner
    应该是公共的

    UPDT
    我们可以考虑<代码>狗>所有者>代码>作为主数据,以及<代码>人的价值。狗< /代码>作为次级数据,类似于数据库索引。

    您希望关系是内部的(如某人有一个狗的集合作为一个字段,狗有一个所有者作为一个字段)还是外部的(例如一个包含关系的映射)。我假设是内部的,因为规范指定我必须“修改Person类,使Person对象可以作为多达20个Dog对象的所有者。”只需在Person中添加方法setDog(Dog pet),然后在Dog中添加方法setOwner(Person owner)。就这么简单:)霍洛伍德原理;)我不太喜欢“这里:代码!”的回答。一些解释可能会有帮助,否则OP所能做的就是复制、粘贴和hopeI。我已经添加了一个小段落来解释发生了什么,希望能有所帮助。我假设的原因与另一个被否决的答案相同。“这里:代码!”除非是一行,否则答案对任何人都没有帮助。一些解释可能会有帮助,否则OP所能做的就是复制、粘贴,希望我什么时候投票否决?当你遇到令人震惊的问题时,使用你的反对票
    private Dog myDog;
    
    private Dog[] dogArray = new Dog[20];
    OR
    private Collection<Dog> dogList = new ArrayList(20); //for example
    
        Person person = new Person();
        Dog dog1 = new Dog();
        dog1.setAge(12);
    
        Dog dog2 = new Dog();
        dog2.setAge(34);
    
        person.addDog(dog1); //dog 1
        person.addDog(dog2); //dog 2
        person.listDogs(); //list of all dogs
    
    public class Person {
     // instance variables - replace the example below with your own
        private String name;
        private int age;
        private String address;
        private ArrayList<Dog> dogs = new ArrayList<Dog>();
    
    
    
        /**
         * Constructor for objects of class Person
         */
        public Person()
        {
           this.name = name;
           this.age = age;
           this.address = address;
        }
    
        public void addDog(Dog dog) {
            this.dogs.add(dog);
        }
    
        public void listDogs() {
            for(Dog item : this.dogs) {
                System.out.println(item.getAge());
            }
        }
    
    
    
        //Set Methods: 
        public void setName () {
                this.name = name;
        }
    
    
        public void setAge () {
                this.age = age;
        }
    
    
        public void setAddress () {
                this.address = address;
        }
    
    
        //Get Methods: 
        public String getName () {
                return name;
        }
    
        public int getAge () {
                return age;
        }
    
        public String getAddress () {
                return address;
        }
    }
    
    public class Dog {
    
        // instance variables - replace the example below with your own
        private String name;
        private int age;
    
    
    
        public Dog()
        {
           this.name = name;
           this.age = age;
        }
    
    
        //Set Methods:
        public void setName () {
            this.name = name;
        }
    
        public void setAge (int age) {
            this.age = age;
        }
    
        //Get Methods:
        public String getName () {
            return name;
        }
    
        public int getAge () {
            return age;
        }
    
    
    }
    
    public class Person
       Set<Dog> dogs = new HashSet<Dog>();
    
    
       public void addDog(Dog dog){
          if(dogs.size()>20){
               throw new IllegalArgumentException("exceeded the limit: ");         
          }  
          dogs.add(dog);    
       }
    }
    
    public class Dog
    {
        Person person;
    
        public void setPerson(Person person){
            this.person=person;
        }
    }