Presentation is loading. Please wait.

Presentation is loading. Please wait.

Phil Tayco Slide version 1.0 Created Oct 9, 2017

Similar presentations


Presentation on theme: "Phil Tayco Slide version 1.0 Created Oct 9, 2017"— Presentation transcript:

1 Phil Tayco Slide version 1.0 Created Oct 9, 2017
Composition Phil Tayco Slide version 1.0 Created Oct 9, 2017

2 Dates In the previous exercise, you designed a class that involved the use of an expiration date for a grocery item As a String type, the expiration date can be useful for presentation purposes, but not necessarily so for evaluation purposes: Is the expiration date passed the current date? Is the expiration date coming in a week? What about other date related information? To answer these questions with the date stored as a String requires parsing the data Dates can also have multiple formats (US, European, 2 or 4 digit year,…) Extra work can be done to handle these format situations but OO programmers will say this is unnecessary – a Date is a type of data!

3 Dates As we see more examples of classes, we can start applying a consistent approach to defining them All classes have 2 major components: properties/attributes and behaviors (functions/methods) We address properties by asking “what does this class we want to model have?” We address behaviors by asking “what do we want this class to be able to do?”

4 Date Properties With properties, once we establish some of them, we ask what their respective data types will be For a Date class here, we may want to define that each Date has a month, day and year For each one of these properties, we may want to define their data types all as int That immediately establishes some code: public class Date { private int month; private int day; private int year; }

5 Date Properties Not only that, we immediately have 7 functions to consider: At least a default constructor 3 Set methods for month, day and year properties 3 Get methods Other functions can be developed as well: Multiple constructors (int, int, int) or just (int) Predicate methods to check if the Date is valid or is a leap year Note how we develop and test the Date class functions – it is treated as a stand-alone class It is also useful to develop a method that creates a String version of the object (in Java, this is the toString() method)

6 Back to Student Not let’s return to the Student class and add a property to the Student class to support date of birth: public class Student { private int id; private String dateOfBirth; } This is a nice start and easily supported, but as mentioned, it is limited in what you can do with it to do any evaluation with the dateOfBirth (isAdult predicate function, for example) Remember when selecting a property, that we have to choose a data type What is a class? It’s a complex data type! Thus, like using a String, it is just as possible to use a class like Date!

7 Composition public class Student { private int id; private Date dateOfBirth; } Classes that contain properties that are other classes you’ve made is designing using “Composition” How does this complicate matters? There is definitely more to keep in mind when completing the class design, but the rule of thumb is to keep development consistent: Once you defined the properties, create the constructors and supporting methods as normal The purpose of a constructor is to initialize all properties of the object at instantiation. To initialize a property with a class data type, you are creating another object

8 Default Constructor dateOfBirth is initialized by instantiating it
public Student() { id = -1; dateOfBirth = new Date(); } dateOfBirth is initialized by instantiating it The constructor is where all properties of an object take form. By instantiating properties in a constructor, it helps ensure complex objects are instantiated only at construction Why did we use the default constructor of Date() in this example? Consider the next constructor example

9 Another Constructor public Student(int i, int m, int d, int y) { id = i; dateOfBirth = new Date(m, d, y); } dateOfBirth is initialized using the constructor that receives 3 integers The 3 integers are provided through the instantiation of the Student constructor – this means the code creating the Student object must know to provide 4 integers for id, month, day and year (an API comes in handy here) For the default constructor, it was not given any values to use to create a Date object – that is why we used the default Date constructor What if we had a Student constructor that only took one integer for id?

10 Another Constructor public Student(int i) { id = i; dateOfBirth = new Date(); } Like the default Student constructor, we don’t have enough information to instantiate dateOfBirth We have information for id, but that’s it so we have to instantiate dateOfBirth with the default This stresses the importance of having a default constructor. In this example, other classes are using the class as a property and may not have enough information to instantiate, thus relying on the use of a default Now let’s move to other functions – how can we check if a Student was born before 2000?

11 Predicates public boolean isMillennial() { return (dateOfBirth.getYear() >= 2000); } Note the signature for this predicate function – it returns a boolean and we are using information already inherent within the object – this is consistent as we’ve seen with other predicates In this case, the property to use is dateOfBirth and specifically, we need to see if the year is before 2000 Note we have to use getYear() to do this – even though dateOfBirth is using Date in Student, the properties of Date are hidden

12 Testing Complex Objects
Don’t forget the main program. At first we used it to test Date objects. Now we can add testing Student objects as well public static void main(String args[]) { Student s1 = new Student(); Student s2 = new Student(101, 5, 19, 1995); if (s2.isMillennial()) System.out.println(“Young”); } It seems straightforward but also raises questions How does creating a String version of a Student change? Can I create a Student object with a Date object? How does this impact the set methods for Student? How would I design the Student object to maintain age?

13 Complex Objects as Strings
public String toString() // this is defined in Student { return String.format( ??? ) } With the Date class’ toString function, we created a String version of the object by making a String from the month, day and year properties We can do the same thing with a Student object by looking to create a String from the Student’s id and dateOfBirth We are fortunate in Java that this is automatically done by it implicitly calling the toString function of a class when a String version of an object is needed

14 Complex Objects as Strings
public String toString() // this is defined in Student { return String.format(“%d:%s”, id, dateOfBirth); } This returns a String version of a Student object by implicitly calling the toString function of the Date class when we need a String version of the dateOfBirth This allows for separate and parallel maintenance of Student and Date classes because of their stand-alone ability (you can change the toString function in Date and affect Student) Class design rule of thumb: design properties, create constructors, set/get methods and a function to create a String version of the object

15 Objects as Parameters Since objects are instances of data types, we can use them in function calling, but you have to be careful because this is call by reference! public static void main(String args[]) { Date d1 = new Date(2, 29, 1996); Student s5 = new Student(102, d1); } Here we are creating a Student object s5 using a Date object already created in d1 This means we need a constructor in Student that takes Date as an input parameter. No problem right?

16 Objects as Parameters public Student(int i, Date d) { id = i; dateOfBirth = d; } Here we are given a Date object as an input parameter stored in d and using that to assign the object’s dateOfBirth property to it This seems okay, but note that this the Date object is a pass by reference which means “d” here is a reference to the original Date object created (which is “d1” in main)

17 Objects as Parameters Current picture after the constructor is called
s5’s dateOfBirth points to the same object as d1 Most important: main doesn’t know this!! s5 102 d1 0x1234abcd 0x1234abcd 2 29 1996

18 Objects as Parameters Now when we change d1 in main, we change s5’s dateOfBirth as well! public static void main(String args[]) { d1.setMonth(10); System.out.println(s5); } This may actually be something you want to do or it may not Most important is to know that this is going on and occurs with all objects that are passed into functions To separate this, we can use the information from the d1 object passed in to create a new instance of dateOfBirth in the constructor

19 Objects as Parameters public Student(int i, Date d) { id = i; dateOfBirth = new Date(d.getMonth(), d.getDay(), d.getYear()); } Here we are using the given Date object to “get” all the object properties The dateOfBirth is explicitly creating a “new” Date object when the Student object is created – this will earn its own place in memory that is separate from d1

20 Objects as Parameters Current picture after the constructor is called
d1 can now be changed in main independent of s5 and vice versa with s5’s dateOfBirth s5 102 d1 0x1234abcd 0x3f4a2290 2 29 1996 2 29 1996

21 Set Methods This leads into the next question on how set methods should be designed As class designer, we get to decide what to make available - set with a specific sub-properties or with an object public static void main(String args[]) { d2 = new Date(4, 8, 1960); s5.setDateOfBirth(3, 29, 2007); s5.setDateOfBirth(d2); } Note that both “setDateOfBirth” properties have the same name but with different input parameter types…

22 Set Methods With Composition, overloading set methods make sense
public void setDateOfBirth(int m, int d, int y) { month = m; day = d; year = y; } public void setDateOfBirth(Date d) month = d.getMonth(); day = d.getDay(); year = d.getYear(); Why didn’t we create a new Date object in the 2nd setDateOfBirth method? Could we create a setDateOfBirth(int) method?

23 Other Properties What about an age property for Student? We could take the traditional approach: public class Student { private Date dateOfBirth; int age; } This means we create the normal adjustments to constructors, toString, set/get methods etc. age is available for immediate use, but now the question is, does its value need to be stored? By storing it, the value would need to be maintained appropriately, particularly when: dateOfBirth changes The Student object “has a birthday”

24 Other Properties If you store the value, simply saying “return age” in the “getAge()” method might be inaccurate Calculating age is a function of date of birth and current day. Since you have access to these values, getAge may be better designed to calculate on the fly: public int getAge() { // Date currentDate = code to get System date // Return age based on currentDate and dateOfBirth } The pseudocode here implies more work every time getAge is required but may be considered a more reliable value when obtaining the Student object’s age

25 Summary Composition is the design of a class where one of its properties is another class you’ve created All classes designed this way are treated independently – one class does not know it is being used in another Maintaining code with composition is more complex but the concepts are still all applied consistently as if the properties were simple data types Passing objects as input parameters are by reference which is significant for constructors Modifying set and get methods may be necessary depending on the class and property context Good to develop a method to return a String version of the object (toString in Java)

26 Exercise 4 Create a DateTime class and a Time class For the Time class
Create integer hour, minute and second Set/get methods for each property 1 default 1 constructor of for all 3 integers A predicate method for “isValid” to make sure hour, minute and second are in the proper ranges (hour from 0-23, minute and second from 0-59) For the DateTime class Create integer month, day, year properties Create Time time property 1 default constructor 1 constructor with 6 integers for month, day, year, hour, minute and seconds 1 constructor with 3 integers for month day and year and a Time object t that creates a separate time object Use the isValid function in Time appropriately


Download ppt "Phil Tayco Slide version 1.0 Created Oct 9, 2017"

Similar presentations


Ads by Google