COMP1406 - Tutorial #2
Interacting Objects



 

Purpose:

The purpose of this tutorial is to give you practice creating java objects that interact with each other. Read the discussion below on interacting objects, then compile and run the demo code and, finally, proceed with the problems. In addition we will introduce, or review, the use of enum enumerations and also make use of static methods.

Interacting Objects

Objects interact when they access each others data, or invoke each others methods. More specifically, if the code of one object's method accesses another object's data, or invokes another object's method, they are interacting. In this tutorial we will create objects that interact with each other.

In order for objects to interact they must have knowledge of each other. There are two ways to establish this awareness.

1) An object can contain a variable that refers to the other object it needs to interact with. For example, in the following class Person, the Person father and Person mother variables would refer to other Person objects.

class Person{

    String firstName;
    String lastName;
    Person father;
    Person mother;

    void print(){...}

}

If the print() method of a Person object is supposed to print both the object's name as well as the name of its father and mother, the print() method might look like this:

void print(){

    System.out.println("person: " + firstName + " " + lastName);
    System.out.println("father: " + father.firstName + " " + father.lastName);
    System.out.println("mother: " + mother.firstName + " " + mother.lastName);

}

Then, in a java statement like p.print();, the object p will be interacting with the Person objects referred to by its father and mother variables. That is, the method print() running on behalf of object p will be accessing the data of the other Person objects father and mother.

2)The second way that an object can interact with others is by having access to a collection that contains the objects it must interact with. That is, it might not have variables that refer directly to the other objects, but rather a variable that refers to a collection of those objects. Consider a class Course that is meant to model a course offering like COMP 1406 Winter 2012. The class might look like this.

class Course {

    String courseCode; //e.g. COMP1406
    String term; //e.g. Winter 2012
    Person instructor;
    int numberOfStudents;
    Person[] students;

    void print(){...}

}

Suppose further that the print() method should print not only the courseCode, term, and instructor but also the names of all the students. The method print() can interact directly with the instructor object because there is a variable, instructor, that refers to it. To interact with the students, however, the collection of students, an array in this case, must be searched to find those objects. The objects that are being interacted with will be anonymous in that they have no specific named variable that refers to them. The print method might look like this:

void print(){

    System.out.println("course: " + courseCode + " " + term);
    System.out.println("instructor: " + instructor.firstName + " " + instructor.lastName);
    System.out.println("students:");
    System.out.println("=========");

    for(int i=0; i<numberOfStudents; i++)
        System.out.println(students[i].firstName + " " + student[i].lastName);
}
 

Finally, notice from the above examples that interacting objects can be the same kind, e.g. two Person objects interacting, or be different kinds, e.g. a Course object interacting with a Person object.


Demonstration:

Open the java file Demo1Main.java within JCreator and examine the code. Compile the program and run it. It should produce an output as shown below.

 

The demonstration code consists of a Demo1Main class, a Person class and an RelationshipStatus enum. Examine the code and make sure you understand it. If you have not been exposed to enum's yet, here is an explanation.

An enum, or enumeration, defines a new type and a collection of symbolic constants that can be assigned to that type. In the example code the enum:

public enum RelationshipStatus {
    SINGLE,
    IN_RELATIONSHIP_WITH,
    MARRIED_TO,
    ITS_COMPLICATED,
    NOT_SPECIFIED
}

 defines the new type RelationshipStatus and defines the symbolic constants that can be assigned to it. The enum definition looks much like a class definition and should  appear in its own .java file by the same name.

At other places in the code then a variables can be declared to be of the type RelationshipStatus, like the variable status in the Person class. Notice in the Person() constructor the variable is assigned a value as follows: status = RelationshipStatus.NOT_SPECIFIED;. To assign a value you must use the name of the enum type, RelationshipStatus, then a dot, then the symbolic value. This convention allows other enums to also use the same symbolic name in their enumerated list of values. Finally notice that the enum's symbolic name gets printed when the variable is printed with System.out.println();

Enums are the prefered way to deal with variables that should only take on a small set of specific values. They can be used, for example, to enumerate the days of the week, the months of the year, the suits in a deck of cards, etc. The alternative would be to use a String or int variable. The trouble with these variables is that other values outside the intended range can be assigned to them often leading to errors. With an enum however, only one of the specified symbolic values can be assigned to a variable of that type. Using enums will make your code more robust.

 


Problem 1

Relating Objects

  

Imagine that we want to use the code to build part of a social networking system like Facebook. In our system we want to represent subscribers by Person objects. These Person objects can be in a relationship with one other Person object, and in addition they can be friends with many other Person objects.

For problem 1 we want to build the "in a relationship with" part of this.

Add a Person variable to the Person class that would represent the person that the this object is in a relationship with. Create a Person class method void enterRelationshipWith(Person anotherPerson, RelationshipStatus aStatus). This method should allow you to set the relationship if anotherPerson is a valid Person object and aStatus is one of  IN_RELATIONSHIP_WITH, MARRIED_TO Alternatively, if  anotherPerson is null and aStatus is one of SINGLE, ITS_COMPLICATED, NOT_SPECIFIED then the drop any existing relationship and update the status. Finally if the parameters are some other combination that does not make sense then the method should do nothing.

Create a useful Person helper method boolean isInRelatioship() that will answer true if the person is in a relationship with someone else and false otherwise.

Finally modify the Person classes print() method so that if a person is in a relationship their partner's name will get printed as well (See the sample output below).

 

Test you code with the Problem1Main.java file and it should produce an output like that shown below. Then, feel free to alter the Problem1Main.java file to set up a more interesting collection of people and relationships.

 


 

Problem 2

You Gotta Have Friends...

  

Next we want to create the possibility for people to have friends. Modify the Person class and add a Person[] friends variable and initialize it appropriately. Feel free to add any addition helper variables like one to record the current number of friends, or the maximum number of allowed friends etc.

Create two Person instance methods: void addFriend(Person aFriend) and void dropFriend(Person aFriend). The addFriend() method should add aFriend to the this object's collection of friends if they are not already friends and conversely the dropFriend() method should remove aFriend. Be careful that your dropFriend() method does not leave a gap in your friends array that will throw off your code.

Suppose we want to ensure that friendship is mutual. That is, if person p1 is a friend of p2 then p2 must also be a friend of p1. Create the following two static methods to ensure this. Create a Person class static method void establishFriendship(Person p1, Person p2) that will invoke the previous addFriend() method such that p1 is a friend of p2 and also p2 is a friend of p1. create a Person class static method void dropFriendship(Person p1, Person p2) that will invoke the previous dropFriend() method such that p1 is not a friend of p2 and also p2 is not a friend of p1. Do you know why these methods are being declared as static?

Finally, modify the Person class print() procedure to print the names of a person friends as well.

After completing the code modifications you should be able to run the Problem2Main.java code with yours and produce the output shown below. Again feel free to alter the main file to create a more interesting collection of people, relationships and friendships. Or alter the Person print() method so that the output is formatted better.

 

 


 

Problem 3

Different Kinds of Object Interacting

In the previous two problems the interacting objects were all to type Person. For this problem we want to demonstrate objects of different types, Person and Course, interacting. Examine the Problem3Main.java test file provided to see how your code should work.

Create a new class Course that models a course section as explained in the introductory explanation on interacting objects. It should have an Person[] students that would represent all the students enrolled in the course section. Add a void addStudent(Person aPerson) and void dropStudent(Person aPerson) that can be used to add or remove students from the course.

The Course class should have a void announce(String aSubject, String aMessage) method that will send to each student in the course message with subject aSubject and containing aMessage as the body. Add a void receiveMessage(String aSubject, String aMessage) to the Person class by which they can receive a message and which should print the fact that the person received the message.

Test your code with the Problem3Main.java file provide and it should produce and output as shown below. Once it works feel free to change the main code to be more interesting.

 

Once you have finished the above three problems demonstrate them to the tutorial TA to get credit for the tutorial.


 

Problem 4 (Advanced Optional Part)

A Friend of a Friend

Social networks often like to suggest others that you might like to be friends with. For this problem you want to identify transitive friends. A transitive friend is a friend of friend that is not already your friend. (That seemed like a mouthful to say.)  Using the problem 2 code as a start, modify the Person class and provide an new main program so that when people are printed out, not only will it show their friends but also any transitive friends they have. Presumably these transitive friends might be good candidates for future friendships.