CS100J    Spring 2005    Assignment A2    
Due (submitted on the CMS) on Thursday, 17 February

Introduction

Read the WHOLE handout before you begin to write the assignment.

CBC is planning on launching a gritty new drama series, called The Greases, kind of like As the World Turns. The producers of this show have a problem, however: the Grease family is so large that they have trouble keeping track of who is related to whom, what the relation is between any two characters, and which couples can't get married because they're cousins.

That's where you come in, as the CBC's resident computer expert. They've asked you to devise a system that will keep track of all the family members in this show and allow them to add characters and keep track of characters as the show progresses. Make sure that the Java class you implement to store information on Grease family members is a good one --or they may not renew your job for next season.

Requirements

For this assignment, you are required to design two classes. Class FamilyMember is the real one. It has lots of fields and methods, but each method is simple. If you do one thing at a time, not worrying about the overall picture, you should have little trouble.

Class FamilyMemberTester is used to test class FamilyMember. We will describe how to do this on 8-10 February. Do not think too much about it when first reading this handout.

Class FamilyMember

An instance of class FamilyMember represents a single member of a family (in this case, one of the Grease family members). It has several fields that one might use to describe a relative, as well as methods that operate on these fields.

FamilyMember Variables

Class FamilyMember will have the following 11 fields:

Here are a few specifications about the fields of the FamilyMember class:

FamilyMember Methods

Class FamilyMember supports the following methods. Pay close attention to the parameters and return values of each method. The descriptions, while informal, are complete.

Constructor Description

FamilyMember(String first, String last,
String gender,
int day, int month, int age)

Constructor: a new FamilyMember. Parameters are, in order, the first name and last name of the person, their gender, the day and month of their birthday, and their age. The new person is not a criminal.

FamilyMember(String first, String last, String gender,
FamilyMember father, FamilyMember mother,
int day, int month, int age)

Constructor: a new FamilyMember. Parameters are, in order, the first name and last name of the person, their gender, their father and mother (not null), the day and month of their birthday, and their age. The new person is not a criminal.

FamilyMember(String first, String last, String gender,
FamilyMember father, FamilyMember mother)

Constructor: a new FamilyMember. Parameters are (in order) the first name and last name of the person, their gender ("male" or "female"), their father and mother (not null). The new person was born on 1 January, is 0 years old, and is not a criminal.

Method Description

getFirstName()

= the first name of this family member (a String)

getLastName()

= the last name of this family member (a String)

getName()

= the full name of this family member (a String). The format of the name is: the first name, a blank char., and finally the last name. E.g.: "John Mac" is correct; "Mac, John" iswrong.

getAge()

= the age of this family member (an int)

getGender()

= the gender of this family member (a String).

getDOB()

= the day of the month this family member was born (an int).

getMOB()

= the integer that represents the family member's month of birth (an int).

getFather()

= (the name of the object representing) the father of this family member (a FamilyMember).

getMother()

= (the name of the object representing) the mother of this family member (a FamilyMember).

getNumberChildren()

= the number of children of this person (an int).

getFamilySize()

Static method. = the number of people in the entire family --the number of FamilyMember objects created thus far (an int).

isCriminal()

= "this family member is a criminal" (a boolean)

setFirstName(String n)

Set the first name of this family member to n.

setLastName(String n)

Set the last name of this family member to n.

setAge(int age)

Set this family member's age to age.

setGender(String g)

Set the gender of the family member to g (one of "male" and "female").

setDOB(int i)

Set the day of the month this family member was born to i.

setMOB(int i)

Set the month of birth for this family member to i.

setGuilt(boolean b)

Set whether this family member is guilty of a crime to b (true or false).

setFather(FamilyMember fm)

Set this person's father to fm. Precondition: This person's father is null, fm is not null, and fm is male.

setMother(FamilyMember fm)

Set this person's mother to fm. Precondition: This person's mother is null, fm is not null, and fm is female.
   

isOlder(FamilyMember fm)

= "this family member is older than fm" (a boolean). Use only the age field in making this comparison, not the day and month fields. Precondition: fm is not null.

areSameAge(FamilyMember fm1,
FamilyMember fm2)

Static function. = "fm1 and fm2 are not null and are the same age" (a boolean). Use only the age field in making this comparison, not the day/month fields.

areRelated(FamilyMember fm1,
FamilyMember fm2)

Static function. = "fm1 and fm2 are not null and have the same last name" (a boolean). Capitalization is not important --e.g. "Grease" and "grease" are the same last name.

isBrother(FamilyMember fm)

= "fm is this family member's brother" (a boolean). Note: a guy is called your brother if you and he (has to be a "he") are different and have at least one parent in common. Precondition: fm is not null.

isSister(FamilyMember fm)

= "fm is this family member's sister" (a boolean). Note: a gal is called your sister if you and she (has to be a "she") are different and have at least one parent in common. Precondition: fm is not null.

areSiblings(FamilyMember fm1, FamilyMember fm2)

Static method. = "fm1 and fm2 are not null and fm1 and fm2 are siblings (brothers or sisters)" (a boolean).

isMotherOf(FamilyMember fm)

= "this family member is fm's mother" (a boolean). Precondition: fm is not null.

isFatherOf(FamilyMember fm)

= "this family member is fm's father" (a boolean). Precondition: fm is not null.

isParentOf(FamilyMember fm)

= "this family member is fm's parent" (a boolean). Precondition: fm is not null.

areTwins(FamilyMember fm1,
FamilyMember fm2)

Static method. = "fm1 and fm2 are not null and fm1 and fm2 are siblings and have the same age, birth day, and birth month" (a boolean).

isEvilTwin(FamilyMember fm)

= "this family member is an evil twin of fm --'evil' means having a criminal record. Precondition: fm1 is not null.

Make sure that the names of your methods match those listed above exactly, including capitalization. The number of parameters and their order must also match. The best way to do this is to copy and paste. Our testing will be expecting those method name names and parameters, so any mismatch will fail during our testing. Parameter names will not be tested --you can change the parameter names if you want.

Each method must be preceded by an appropriate specification, as a Javadoc comment. The best way to ensure this is to copy and paste. Note that a precondition should not be tested by the method; it is the responsibility of the caller to ensure that the precondition is met. As an example, in method isMotherOf, the method body should not test whether fm is null. However, in function areSiblings, the tests for fm1 and fm2 not null must be made.

The number of children of a newly created person is 0. Whenever person P is made the mother or father of another person, P's number of children should increase by 1.

It is possible for person P1 to be P2's mother, and visa versa, at the same time. We do not check for such strange occurrences.

Your method bodies should have no if statements. Your method bodies should contain only assignments and return statements. Points will be deducted if if statements are used.

Class FamilyMemberTester

How do you know whether class FamilyMember that you are designing is correct? The only way you can be sure is to test it, to see if it does what it is supposed to do. It is not enough simply to try out your class FamilyMember in the interactions pane. Every time you write a method for your class FamilyMember, you should also write a couple of tests for it. And run your collection of tests frequently to make sure that everything works correctly.

The FamilyMemberTester is the JUnit test suite you'll design, which performs these testing tasks for you. Make sure that your test suite adheres to the following principles:

Remember that if you change static variables in an early test, they will retain their values in later tests. Also, the tests are not necessarily run in the order in which you list them in your test suite. So when testing static variables, record their initial value at the beginning of the test, and test that the change in the value is what you expect.

Hints and Tips

    At each step, make sure all methods are correct before proceeding to the next step. When adding a new method, cut and paste the comment and the header from the assignment handout.

      • Microsoft operating systems hide file extensions by default. You should change this so that the extensions ALWAYS appear! Don't let Microsoft tell you what to do.
      • DrJava creates "backup files", which means that you'll see file names like "FamilyMember.java~". The ~ indicates that the file is a backup file, which happens to be an older version of your program.

    Since .class files cannot be read by TAs or run with our testing programs, submitting the wrong files creates havoc with grading your assignment. Every year, a half-dozen students submit the wrong file. Don't do it!