我有一个基本的任务,但我对OOP很新,并且正在努力。其他在线资源开始增加我的困惑。
我被要求:
为类Person编写代码。 Person对象具有属性名称,年龄和地址。
为类Dog编写代码。 Dog对象具有属性名称和年龄。
在Person和Dog类中提供在Person对象和Dog对象之间建立双向关联所需的任何其他代码。 Person对象充当Dog对象的所有者,Dog对象充当Person对象的宠物。
修改您的Person类,以便Person对象可以充当最多20个Dog对象的所有者。
显然这是一个非常简单的例子。
到目前为止我的代码:
人员类:
public class Person
{
// instance variables - replace the example below with your own
private String name;
private int age;
private String address;
/**
* Constructor for objects of class Person
*/
public Person()
{
this.name = name;
this.age = age;
this.address = address;
}
//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 () {
this.age = age;
}
//Get Methods:
public String getName () {
return name;
}
public int getAge () {
return age;
}
}
主要:
public class Main
{
//Blank
}
我知道这段代码目前没用,并且没有做任何事情,但我不确定如何“关联”对象&在哪里做。作业规范指定一个人充当狗的“所有者”。
这就是我的问题所在。设置对象之间的关系。
答案 0 :(得分:7)
这里的主要问题是一致性:如果Dog d1是Person p1的宠物,那么p1必须是d1的所有者,反之亦然。如果像许多人建议的那样,我们有2个方法(Person.addDog()
和Dog.setOwner()
),那么用户很容易犯错并且无法调用这两个方法(或使用错误的参数调用)。由于Dog只能拥有一个所有者,因此简单而安全的界面将使用单一方法Dog.setOwner(Person p)
,如果我们希望狗没有所有者,则p
可能为null。除了设置字段Dog.owner
之外,此方法必须从前一个所有者的宠物列表中删除此狗,并且(如果p!= null)将其自身添加到新所有者的宠物列表中。添加和删除宠物的类Person
的方法对于类Dog
应该是可见的,但对用户不可见(它们应该是包私有的),而方法Dog.setOwner
应该是公共的
答案 1 :(得分:2)
这是双向关系的常见问题;你不能在构造函数中传递它们,因为当另一个初始化时,它还不存在。因此,您必须“从外部连接它们”
你提到的20只狗表明他们希望你用一个阵列来抓住狗,但是一个arraylist会更好。我将使用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)
}
.....
.....
同样,狗类获得了所有者
public class Dog
{
Person owner;
public void setOwner(Person owner){
this.owner=owner;
}
.....
.....
使用这两种方法可以创建双向关系。
这显然是一项任务,所以除了未来之外别无选择;像这样的双向关系可能很有用。但如果使用不当,它们也很危险;最重要的是,在初始化之后,对象必须正常工作。它不能依赖于调用setOwner()或giveDog():换句话说,一个无家伙的人和一个无主的狗必须表现得“正确”(在这种情况下这意味着什么。未能实现这一点可能会导致容易出错的代码。如果这是不切实际的话,那么无主的狗或无狗的人就不可能接触到其他程序;工厂方法对此有用,但这超出了这个问题的范围
答案 2 :(得分:2)
您需要做的事情看起来像circular dependency问题。所以你可以做的是使用object composition。
只需向您的类添加第二种类型的实例变量:
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对象的所有者。
不是让每个Person
对象都有一个Dog
成员,而是使用一个数组或一些Collection(List,Set等):
所以而不是
private Dog myDog;
DO
private Dog[] dogArray = new Dog[20];
OR
private Collection<Dog> dogList = new ArrayList(20); //for example
答案 3 :(得分:2)
由于无法同时创建两个对象,因此无法在构造函数中将引用传递给彼此。您必须创建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;
}
}
答案 4 :(得分:0)
试试这个:
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
<强> // PERSON 强>
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;
}
}
<强> // DOG 强>
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;
}
}