Scopes

Figure 254. Circle and variable scopes Slide presentation Create comment in forum

Figure 255. Documenting classes and methods Slide presentation Create comment in forum
/** Representing circles.
 */
public class Circle {
  private double radius;

  /** Creating a circle.
   *  @param r representing the circle's radius
   */
  public Circle(double r) {
    radius = r;
  }
  public double getDiameter() {
    return 2 * radius;
  }
}

Figure 256. Generated Javadoc Slide presentation Create comment in forum

Figure 257. Refactoring «r» ⇒ «radius» Slide presentation Create comment in forum

Figure 258. Scope assignment problem Slide presentation Create comment in forum
/** Representing circles.
 */
public class Circle {
  private double radius;

  /** Creating a circle.
   *  @param radius Circle's size
   */
  public Circle(double radius) {
    radius = radius; // Warning: Variable 'radius' is assigned to itself.
  }
  public double getDiameter() {
    return 2 * radius;
  }
}

Figure 259. this overriding method scope Slide presentation Create comment in forum

exercise No. 100

Turning seconds into weeks, part 2 Create comment in forum

Q:

This is a follow-up exercise to Turning seconds into weeks implementing a corresponding Timeperiod class. Consider the subsequent example demonstrating both its intended use constructor and toString() method:

final long seconds = 112223;
final Timeperiod t = new Timeperiod(112223);
System.out.println(seconds + " seconds are equal to " + t);
112223 seconds are equal to 1 day, 7 hours, 10 minutes and 23 seconds

Since the toString() method may not be called at all it shall be implemented on demand in analogy to Your personal String class . Tip: create a suitable attribute being null initially. If toString() is being called, first check for null and initialize it on demand only.

Furthermore individual weeks, days, hours, minutes and seconds shall be implemented as read-only values using final:

final Timeperiod t = new Timeperiod(2310983);
System.out.print("weeks = "     + t.weeks +
                 "\ndays = "    + t.days +
                 "\nhours = "   + t.hours +
                 "\nminutes = " + t.minutes +
                 "\nseconds = " + t.seconds);
weeks = 3
days = 5
hours = 17
minutes = 56
seconds = 23

In other words: The Timeperiod class should be implemented as an immutable. Thus once a Timeperiod instance has been created it shall be impossible to alter the instance's values i.e. changing its state.

Use the following tests to check your implementation:

public class TimeperiodTest {

    // Helper methods for real tests.
    static void assertPeriodEqualImplement(final int expectedSeconds,
                          final int expectedMinutes,
                          final int expectedHours,
                          final int expectedDays,
                          final int expectedWeeks,
                          final String expectedToString,
                          final Timeperiod period) {
        Assert.assertEquals(expectedSeconds, period.seconds);
        Assert.assertEquals(expectedMinutes, period.minutes);
        Assert.assertEquals(expectedHours, period.hours);
        Assert.assertEquals(expectedDays, period.days);
        Assert.assertEquals(expectedWeeks, period.weeks);

        Assert.assertEquals(expectedToString, period.toString());

    }

    static void assertPeriodEqual(final int expectedSeconds,
                          final int expectedMinutes,
                          final int expectedHours,
                          final int expectedDays,
                          final int expectedWeeks,
                          final String expectedToString,
                          final Timeperiod period) {

        // Testing period in question
        assertPeriodEqualImplement(
                expectedSeconds, expectedMinutes, expectedHours, expectedDays, expectedWeeks, expectedToString,
                period);

        // Also testing copy constructor
        assertPeriodEqualImplement(
                expectedSeconds, expectedMinutes, expectedHours, expectedDays, expectedWeeks, expectedToString,
                new Timeperiod(period));
    }

    /**
     * Test constructor zero seconds.
     */
        @Test
        public void testZero() {
            assertPeriodEqual(
                    0,0,0,0,0,
                    "0 seconds",
                    new Timeperiod(0));
        }

    @Test
    public void testMinute() {
        assertPeriodEqual(0,1,0,0,0,
                "1 minute and 0 seconds",
                new Timeperiod(60));
        assertPeriodEqual(50,0,0,0,0,
                "50 seconds",
                new Timeperiod(50));
        assertPeriodEqual(12,1,0,0,0,
                "1 minute and 12 seconds",
                new Timeperiod(72));
        assertPeriodEqual(2,5,0,0,0,
                "5 minutes and 2 seconds",
                new Timeperiod(302));
    }

    @Test
    public void testHour() {
        assertPeriodEqual(0,0,2,0,0,
                "2 hours, 0 minutes and 0 seconds",
                new Timeperiod(7200));
        assertPeriodEqual(59,59,0,0,0,
                "59 minutes and 59 seconds",
                new Timeperiod(3599));
        assertPeriodEqual(40,1,1,0,0,
                "1 hour, 1 minute and 40 seconds",
                new Timeperiod(3700));
    }

    @Test
    public void testVarious() {
        assertPeriodEqual(1,3,4,1,6,
                "6 weeks, 1 day, 4 hours, 3 minutes and 1 second",
                new Timeperiod(3729781));

        assertPeriodEqual(23,56,17,5,3,
                "3 weeks, 5 days, 17 hours, 56 minutes and 23 seconds",
                new Timeperiod(2310983));
    }
}

A:

Our implementation basically reads:

public Timeperiod(final Timeperiod timeperiod) {

    public final int seconds, minutes, hours, days, weeks;
    // Constructors and toString() ...

}

The final modifier ensures instances to be immutable requiring all values to be set within any constructor. We thus decompose the desired number of seconds into weeks, days, hours, minutes and remaining seconds:

public Timeperiod(int seconds) {

  weeks = seconds / SECONDS_PER_WEEK;
  seconds = seconds % SECONDS_PER_WEEK;        // remaining seconds without weeks

  days = seconds / SECONDS_PER_DAY;
  seconds %= SECONDS_PER_DAY;                  // remaining seconds without days

  hours = seconds / SECONDS_PER_HOUR;
  seconds %= SECONDS_PER_HOUR;                 // remaining seconds without minutes

  minutes = seconds / SECONDS_PER_MINUTE;
  this.seconds = seconds % SECONDS_PER_MINUTE; // remaining seconds
}

Notice the this.seconds qualification being required to disambiguate the constructor parameter variable Timeperiod(int seconds) from the instance member variable Timeperiod.seconds.