CSE114 Spring 2016 Lab Exercise 2 of Week 6 Classes and Objects: A Person Example Chen-Wei Wang 1 Background Reading So far we have developed the Java code solely within the main method. In fact, in Java we may define more than one classes, and each class may contain more than one methods. Notions of classes and objects in Java make object-oriented programming possible. 1.1 Real Life: Template vs. Instances To understand the idea about object-orientation, it is necessary to appreciate the relationship between a template and its instances. For example, we may have a template called Person, which defines the common – attributes (e.g., age and nationality); and [attributes ≈ nouns] – behaviour (e.g., get older and change nationality) [behaviour ≈ verbs] That is, persons (e.g., jim and jonathan) share these common attributes and behaviour. On the one hand, each person possesses an age and a nationality. On the other hand, each person’s age and nationality might be distinct: e.g., jim who is 50-years old is a British, jonathan who is 65-years old is a Canadian. Consequently, the resulting behaviour of each person, depending on the specific values of their attributes, might be distinct: when Jim gets older, he becomes 51, whereas when Jonathan gets older, he becomes 66. Similarly, if Jim changes his nationality to Korean, it is a transition from British to Korean, whereas the same change of nationality for Jonathan will be a transition from Canadian to Korean. From the above example, we make the following general observations: – A template (e.g., Person) defines the common attributes (e.g., age, nationality) and behaviour (e.g., get older and change nationality) that are shared by a set of entities. – Each template may be instantiated into multiple instances (e.g., jim and jonathan). – Each instance may have specific values for the attributes (e.g., 50-years old British and 65-years old Canadian), and thus exhibit distinct behaviour (e.g., Jim getting older from 50 to 51 and changing nationality to Korean from British versus Jonathan getting older from 65 to 66 and changing nationality to Korean from Canadian). 1.2 Java Class In Java, you use a class to define a template that summarizes common attributes that are shared by a set of entities. For example: 1 public class Person { 2 int age; 3 String nationality; 1 4 void getOlder() { /* ordinary method */ 5 age = age + 1; 6 } 7 void changeNationality(String newNationality) { /* ordinary method */ 8 nationality = newNationality; 9 } 10 Person(int initAge, String initNationality) { /* special method: constructor */ 11 age = initAge; 12 nationality = initNationality; 13 } 14 } In the above Java code: – Lines 2 and 3 declare, respectively, an integer variable age and a string variable nationality. Each of these variables are considered as an attribute of the Person class. – Values of attributes may be changed by methods that model the behaviour of a Person: – Lines 4 to 6 define an ordinary method getOlder that models the behaviour of a person getting older. The signature of that method indicates that it takes no inputs/parameters, and does not return anything as an output. – Lines 7 to 9 define an ordinary method changeNationality that models the behaviour of a person changing their nationality. The signature of that method indicates that it takes as an input/parameter a new nationality of type String, and does not return anything as an output. – Lines 10 to 13 define a special method called the constructor for the Person class. From its signature, you can observe that its name matches the name of the class (i.e., Persons), and this suggests that it cannot be used like an ordinary method. This is why you cannot see it having a return/output type. Furthermore, this constructor takes as inputs/parameters an initial age and an initial nationality for creating a new instance of Person (which we will see how in the next subsection). 1.3 Java Objects and Testers Once a class is defined, you will want to test it by instantiating it into objects that: – On the one hand possess these common attributes; but – One the other hand bears instance-specific values for these attributes. Where should we test the Person class? You are not advised to write tests in the same Person class: this is because we would like to have a separation of concerns between business logic (i.e., Person) and tests (i.e., manipulation of instances of Persons). Therefore, we create a new class PersonTestser that is dedicated to the testing of Person. 1 public class PersonTester { 2 public static void main(String[] args) { 3 Person jim = new Person(50, "British"); 4 System.out.println("Jim is " + jim.age + " years-old and is a " + jim.nationality); 5 jim.getOlder(); 6 jim.changeNationality("Korean"); 7 System.out.println("Jim is " + jim.age + " years-old and is a " + jim.nationality); 8 } 9 } Let us examine the above code line by line: 2 – Line 1 declares a class PersonTester dedicated to the task of testing the Person template. – Line 2 declares the main method that will be treated as the entry point of execution for the Java application. – Line 3 instantiates the Person class, with age 50 and nationality "British", and name that instance as jim. Here argument values 50 and "British" conform to the types of parameters initAge and initNationality of the constructor defined in the Persons class. We say jim is a reference to an object of type Person. – Line 4 prints information about the object referred to by jim. To retrieve an attribute of jim, we use the . (dotted) notation: e.g., jim.age and jim.nationality. – Liens 5 and 6 exhibit the behaviour of jim getting older and changing his nationality. Similar to the case of retrieving attributes, we again use the . (dotted) notation to call methods on the object that is referred to by jim: e.g., jim.getOlder() and jim.changeNationaltiy("Korean"). Notice that the argument value "Korean" conforms to the type of parameter newNationality of the changeNationality method in the Person class. – Line 7 is exactly the same as Line 4. However, as in Lines 5 and 6 jim has changed his age and nationality, the output to the console, as expected, will be different! 2 Your Tasks In the Person class: 1. Define a method getAge that returns the age of the person. What should be the proper signature of this method? 2. Define a method getNationality that returns the nationality of the person. What should be the proper signature of this method? 3. Define a method isMiddleAged that decides if the person’s age is above 50. What should be the proper signature of this method? 4. Define two new attributes: firstName and lastName. Then define two methods getFirstName and getLastName that return the person’s first and last names, respectively. What should be the proper signature of these two methods? 5. Define a new attribute spouse that is just another person. Then define a method marry that allows a person to marry another. What should be the proper signature of this method? 6. Create an array of person objects, whose ages range from 18 to 72, then write a for loop that prints out the first name, last name, and nationality of those who are older than 50. For each of the above new methods, first think carefully about its appropriate signature, and then test it in the PersonTester class. 3