Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
STREAM A software process The Mañana Principle Don’t try to everything at once! Static Methods Stateless Utility Functions STREAM S tubs T ests R epresentation E valuation A ttributes M ethods Example • Wanted: a class to represent a Date. • Must have the following two methods: - setToNextDay : no parameters - toString : no parameters, returns String with format “<year>-<month>-<day>” Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 1. Stubs class Date { /** * Advance the date to the next day */ public void setToNextDay () { } /** * @return A representation of this date * in the format <year>-<month>-<day> */ public String toString () { return null; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2. Tests The Date class can already be compiled. Using BlueJ, we can immediately create an instance and start testing its methods. Of course, they won’t do much just yet! Make a list of some simple tests we would like to make. To carry out those tests, what else will we need in the Date class? We’ll need a way to set a particular date – only then can we tell if setToNextDay and toString work. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2. Tests So, just by thinking about testing, we see the need for another method. This is cohesion in action! class Date { /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } ... setToNextDay method (as before) ... toString method (as before) } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3. Representations R1: use three integer fields - day (1..31), month (1..12), year (1..) R2: use one integer field - the number of days since 1st. January, 1970 Many others are possible … Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3. Evaluate R1: use three integer fields - day (1..31), month (1..12), year (1..) R2: use one integer field - the number of days since 1st. January, 1970 Implementation Effort R1 R2 setToNextDay toString Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The TEACH Scale Trivial Easy Average Challenging Hard difficulty Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3. Evaluate R1: use three integer fields - day (1..31), month (1..12), year (1..) R2: use one integer field - the number of days since 1st. January, 1970 Implementation Effort R1 R2 setToNextDay Challenging Trivial toString Trivial Hard Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5. Attributes (we call them fields) R1: use three integer fields - day (1..31), month (1..12), year (1..) class Date { private int day; private int month; private int year; // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year ... setDate (as before) ... setToNextDay method (as before) ... toString method (as before) } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5. Attributes (we call them fields) R2: use one integer field - the number of days since 1st. January, 1970 class Date { private int date; // days since 1970-01-01 ... setDate (as before) ... setToNextDay method (as before) ... toString method (as before) } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R1 class Date { private int day; private int month; private int year; ... // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year setDate and setToNextDay methods /** * @return A representation of this date * in the format <year>-<month>-<day> */ public String toString () { return year + "-" + month + "-" + day; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R2 class Date { private int date; ... // days since 1970-01-01 setDate and setToNextDay methods /** * @return A representation of this date * in the format <year>-<month>-<day> */ public String toString () { ... tricky !!! } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R2 class Date { private int date; ... // days since 1970-01-01 setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { date = date + 1; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R1 class Date { private int day; private int month; private int year; ... // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; ... more stuff needed } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle When – during implementation of a method – we wish we had a certain support method, write our code as if we had it. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Special WhenCase – during Rule: implementation Often, we needoftoaidentify method and – we deal wish with weahad special a certain case. Write support themethod, code forwrite this in oura code separate as if we method. had it. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R1 class Date { private int day; private int month; private int year; ... // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; ... more stuff needed checkDayOverflow (); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; checkDayOverflow (); } R1 /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; } checkMonthOverflow (); } } } /** * Spot and deal with special month case */ private void checkMonthOverflow () { if (month > 12) { month = 1; year = year + 1; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 The Mañana Principle Hard Problem Rule: when we need the answer to a problem we cannot immediately solve, defer it a separate method. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > daysInMonth 30) { ()) { day = 1; month = month + 1; checkMonthOverflow (); } } R1 /** * @return The number of days in the month */ private int daysInMonth () { return 30; } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; private int month; private int year; R1 // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... other methods /** * @return The number of days in the month */ private int daysInMonth () { return monthDays[month 30; – 1]; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { ... R1 day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... other methods /** * @return The number of days in the month */ private int daysInMonth () { return int answer monthDays[month = monthDays[month – 1]; – 1]; } if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } }Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle HardFunctionality Problem Rule: Heavy Rule: when need the answer when we some statements or to a problembecome we cannot expressions too immediately solve, defer it a long or complex, move them method. intoseparate a separate method. Implement Implement itit later. later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } R1 /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @param d The divisor * @param n The number being divided * @return Whether d divides n exactly */ private boolean divides (int d, int n) { return (n % d) == 0; } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2. Tests So, just by thinking about testing, we see the need for another method. This is cohesion in action! class Date { /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } ... setToNextDay method (as before) ... toString method (as before) } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 class Date { private int day; private int month; private int year; // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; } ... setToNextDay and toString methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { defer this.day = day; decision as this.month = month; to what is this.year = year; legal !! if (!legalDate ()) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 0001-01-01"); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= daysInMonth 30)) && ())) && ((1 <= month) && (month <= 12)) && (1 <= year); } BUG: if month is not in the range 1..12, daysInMonth() will crash. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { ... R1 day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... other methods /** * @return The number of days in the month */ private int daysInMonth () { return int answer monthDays[month = monthDays[month – 1]; – 1]; } if ((month == 2) && isLeapYear ()) { answer = answer + 1; } Assumes: month is in return answer; } the range 1..12. }Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 /** * @return Whether the date fields are legal */ private boolean legalDate () { return (1 ((1<= <=year) day) && ((1(day <= month) <= daysInMonth && ())) && ((1(month <= month) <= 12)) && && ((1(month <= day) <=&& 12)) && (1 (day <= year); <= daysInMonth ())); } FIXED: operands of && are evaluated BUG: if monthIf is any not operand in the range 1..12, left-to-right. is false, will remaining crash. thedaysInMonth() result is false and operands (if any) are not evaluated. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling STREAM • • • • • • S tubs T ests R epresentation E valuation A ttributes M ethods Our choice of representation can have great impact on the complexity of the logic. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5. Attributes (we call them fields) R2: use one integer field - the number of days since 1st. January, 1970 class Date { private int date; // days since 1970-01-01 ... setDate (as before) ... setToNextDay method (as before) ... toString method (as before) } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R2 class Date { private int date; ... // days since 1970-01-01 setDate and setToNextDay methods /** * @return A representation of this date * in the format <year>-<month>-<day> */ public String toString () { ... tricky !!! } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R2 class Date { private int date; ... // days since 1970-01-01 setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { date = date + 1; } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6. Method Implementation R2 class Date { private int date; ... // days since 1970-01-01 setToNextDay and toString methods /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { ... tricky !!! } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { But the R2 Date has this.day = day; no day, month or year this.month = month; fields to set … this.year = year; if (!legalDate ()) { … and legalDate has this.day = 1; no fields on which it this.month = 1; to operate. this.year = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 0001-01-01"); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { ... still tricky setLegalDate (day,!!! month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 1970-01-01"); } defer } decision as defer hard to what is logic !! legal !! Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 /** * Set the date to a particular day * * @param day (assume: 1 ≤ day ≤ daysInMonth) * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * */ private void setLegalDate (int day, int month, int year) { ... still tricky !!! } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { ... still tricky setLegalDate (day,!!! month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" to "++ " 1970-01-01"); } defer } decision as defer hard to what is logic !! legal !! Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { … but daysInMonth has return (1 <= year) && no month or year fields ((1 <= month) && on which to operate. (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); X X } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && … so we must ((1 <= month) && supply them. (month <= 12)) && ((1 <= day) && (day <= daysInMonth (month, ())); year))); } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { ... R1 day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... other methods /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } Assumes: month is in return answer; } the range 1..12. }Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; R2 // days since 1970-01-01 private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, ... , 31}; /** * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * @return The number of days in the month */ private int daysInMonth (int month, int year) { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear (year)) { answer = answer + 1; } no year field … so return answer; } we must supply. }Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 /** * @param year (assume: 1 ≤ year) * @return Whether the year is a leap year */ private boolean isLeapYear (int year) { return (divides (4, year) && !divides (100, year)) || divides (400, year); } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 class Date { private int day; private int month; private int year; ... // 1 ≤ day ≤ daysInMonth // 1 ≤ month ≤ 12 // 1 ≤ year setDate, setToNextDay, toString methods private int daysInMonth () { ... } private boolean isLeapYear () { ... } private boolean legalDate () { ... } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 class Date { private int date; ... // days since 1970-01-01 setDate, setToNextDay, toString methods private int daysInMonth (int month, int year) { ... } private boolean isLeapYear (int year) { ... } private boolean legalDate (int day, int month, int year) { ... } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling OBSERVATION: We could have used the fully parametrised versions: int daysInMonth (int month, int year) boolean isLeapYear (int year) boolean legalDate (int day, int month, int year) in the R1 version of Date, as well as in version R2 . They do not depend on any chosen field representation. They may, therefore, be worth factoring out into a separate class, DateStuff, which either representation for Date could use. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public int daysInMonth (int month, int year) { ... } public boolean isLeapYear (int year) { ... } public boolean legalDate (int day, int month, int year) { ... } private boolean divides (int d, int n) { ... } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling DateStuff But, now that they are public methods, daysInMonth and isLeapYear must be protected against misuse. public int daysInMonth (int month, int year) { ... } public boolean isLeapYear (int year) { ... } public boolean legalDate (int day, int month, int year) { ... } Note: legalDate is already secure – dealing with bad data is, after all, its purpose! Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling DateStuff /** * @param month (1 ≤ month ≤ 12) * @param year (1 ≤ year) * @return The number of days in the month */ public int daysInMonth (int month, int year) { if ((month < 1) || (month > 12) || (year < 1)) { System.out.println ("*** daysInMonth: bad argument(s)" + " – returning zero"); return 0; } int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear (year)) { answer = answer + 1; } return answer; } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling DateStuff /** * @param year (1 ≤ year) * @return Whether year is a leap year */ public boolean isLeapYear (int year) { if (year < 1){ System.out.println ("*** isLeapYear: bad argument " + "– returning false"); return false; } return (divides (4, year) && !divides (100, year)) || divides (400, year); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling DateStuff /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ public boolean legalDate * (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth (month, year))); } * except that now it’s public. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public int daysInMonth (int month, int year) { ... } public boolean isLeapYear (int year) { ... } public boolean legalDate (int day, int month, int year) { ... } private boolean divides (int d, int n) { ... } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public static int daysInMonth int daysInMonth (int month, ( ...int ) year) { ... } public static booleanboolean isLeapYear isLeapYear (int year) (int year) { ... } public static booleanboolean legalDate legalDate (int day, int month, int year) { ... } private static booleanboolean dividesdivides (int d,(int int n) d, int n) { ... } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling New Java Concept: Methods, as well as fields, may be declared static. static methods may work with fields of its class, but only if they are static. static methods may invoke other methods of its class, but only if they are static. In DateStuff, the methods isLeapYear and divides work only with their parameters – no fields. In DateStuff, the methods daysInMonth and legalDate work with their parameters and (the static field) monthDays. In DateStuff, daysInMonth invokes isLeapYear, which invokes divides. And legalDate invokes daysInMonth. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public static int daysInMonth ( ... ) { ... } public static boolean isLeapYear (int year) { ... } public static boolean legalDate (int day, int month, int year) { ... } private static boolean divides (int d, int n) { ... } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling New Java Concept: Methods, as well as fields, may be declared static. static methods may work with fields of its class, but only if they are static. static methods may invoke other methods of its class, but only if they are static. static fields and methods belong to the class. They are shared by all objects (if any) of the class. To invoke a static method of another class, we don’t need an object of that other class. We invoke it prefixed with the name of its owning class (followed by the usual dot). Normally: we invoke a method on an object. We invoke it prefixed with the name of the variable referencing the object (followed by the usual dot). Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 1970-01-01"); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R2 R2 /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (DateStuff.legalDate (legalDate (day, month, (day, year)) month, { year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 1970-01-01"); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate (){ this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 0001-01-01"); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling R1 R1 /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!DateStuff.legalDate (!legalDate (){ (day, month, year) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + " ... setting date to" + " 0001-01-01"); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling New Java Concept: Methods, as well as fields, may be declared static. static methods may work with fields of its class, but only if they are static. static methods may invoke other methods of its class, but only if they are static. static fields and methods belong to the class. They are shared by all objects (if any) of the class. To invoke a static method of another class, we don’t need an object of that other class. We invoke it prefixed with the name of its owning class (followed by the usual dot). Classes with only static fields and methods need no objects constructed from them. So … hide the constructor!! Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { ... monthDays (private static field) constructor private DateStuff () { // deliberately empty } ... daysInMonth, isLeapYear, legalDate (public static methods) ... divides (private static method) } This class doesn’t construct any instances of itself. Its constructor is private, so nobody else can. There can be no DateStuff objects. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling OBSERVATION: We could have used the fully parametrised versions: int daysInMonth (int month, int year) boolean isLeapYear (int year) boolean legalDate (int day, int month, int year) in the R1 version of Date, as well as in version R2 . They do not depend on any chosen field representation. They may, therefore, be worth factoring out into a separate class, DateStuff, which either representation for Date could use. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling They may, therefore, be worth factoring out into a separate class, DateStuff, which either representation for Date could use. DateStuff contains a set of utility functions that work just with their parameters. They need no persistent state to be held in fields. Such things are very reusable. DateStuff can be used with either the R1 or R2 choice for representation of a date in the Date class. Factoring out these low-level functions into DateStuff leaves the Date class (R1 or R2) shorter. Collections of purely static methods are how we used to do things – before Object-Orientation. Don’t make a habit of it! Objects carrying their own state are powerful!! Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle When – during implementation of a method – we wish we had a certain support method, write our code as if we had it. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Special WhenCase – during Rule: implementation Often, we needoftoaidentify method and – we deal wish with weahad special a certain case. Write support themethod, code forwrite this in oura code separate as if we method. had it. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Hard Special Problem Case Rule: Rule: when Often,we weneed needthe to identify answer andtodeal a problem with a special we cannot case. immediately Write the code solve, for defer this initaa separate method. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle HardFunctionality Problem Rule: Heavy Rule: when need the answer when we some statements or to a problembecome we cannot expressions too immediately solve, defer it a long or complex, move them method. intoseparate a separate method. Implement Implement itit later. later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Heavy Functionality Rule: Nested Loop Rule: when statements whensome we have a nestedor expressions become too loop, move the inner loop long them intooracomplex, separatemove method. intoImplement a separateit method. later. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Code Duplication Rule: Nested Loop Rule: when we repeat the same when we have a nested code, move that code into a loop, move the inner loop separate method and repeat into a separate method. an invocation instead. Implement it later. Implement it later. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling Mañana – Specific Forms • • • • • Special Case rule Hard Problem rule Heavy Functionality rule Nested Loop rule Code Duplication rule Utility Classes public static methods, as well as private static fields. Utility classes (like DateStuff) have only the above kind of methods and fields. Utility classes (like DateStuff) have only private constructors – no objects can be constructed. public static methods are invoked via the class name – no object is needed.