Time Class Case Study

Time1 Class Declaration

Our first example consists of two classesTime1 (Fig. 9.1) and Time1Test (Fig. 9.2). Class Time1 represents the time of day. Class Time1Test is a testing class in which the Main method creates an object of class Time1 and invokes its methods. The output of this application appears in Fig. 9.2.

Figure 9.1. Time1 class declaration maintains the time in 24-hour format.

 1 // Fig. 9.1: Time1.cs
 2 // Time1 class declaration maintains the time in 24-hour format.
 3 public class Time1
 4 {
 5 private int hour; // 0 - 23 
 6 private int minute; // 0 - 59
 7 private int second; // 0 - 59
 8
 9 // set a new time value using universal time; ensure that
10 // the data remains consistent by setting invalid values to zero
11 public void SetTime( int h, int m, int s )
12 {
13 hour = ( ( h >= 0 && h < 24 ) ? h : 0 ); // validate hour
14 minute = ( ( m >= 0 && m < 60 ) ? m : 0 ); // validate minute
15 second = ( ( s >= 0 && s < 60 ) ? s : 0 ); // validate second
16 } // end method SetTime
17
18 // convert to string in universal-time format (HH:MM:SS)
19 public string ToUniversalString()
20 {
21 return string.Format( "{0:D2}:{1:D2}:{2:D2}",
22  hour, minute, second ); 
23 } // end method ToUniversalString
24
25 // convert to string in standard-time format (H:MM:SS AM or PM)
26 public override string ToString()
27 {
28 return string.Format( "{0}:{1:D2}:{2:D2} {3}", 
29  ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 ),
30  minute, second, ( hour < 12 ? "AM" : "PM" ) ); 
31 } // end method ToString
32 } // end class Time1

Figure 9.2. Time1 object used in an application.

(This item is displayed on pages 412 - 413 in the print version)

 1 // Fig. 9.2: Time1Test.cs
 2 // Time1 object used in an application.
 3 using System;
 4
 5 public class Time1Test
 6 {
 7 public static void Main( string[] args )
 8 {
 9 // create and initialize a Time1 object
10 Time1 time = new Time1(); // invokes Time1 constructor
11
12 // output string representations of the time
13 Console.Write( "The initial universal time is: " );
14 Console.WriteLine( time.ToUniversalString() );
15 Console.Write( "The initial standard time is: " );
16 Console.WriteLine( time.ToString() );
17 Console.WriteLine(); // output a blank line
18
19 // change time and output updated time
20 time.SetTime( 13, 27, 6 );
21 Console.Write( "Universal time after SetTime is: " );
22 Console.WriteLine( time.ToUniversalString() );
23 Console.Write( "Standard time after SetTime is: " );
24 Console.WriteLine( time.ToString() );
25 Console.WriteLine(); // output a blank line
26
27 // set time with invalid values; output updated time
28 time.SetTime( 99, 99, 99 );
29 Console.WriteLine( "After attempting invalid settings:" );
30 Console.Write( "Universal time: " );
31 Console.WriteLine( time.ToUniversalString() );
32 Console.Write( "Standard time: " );
33 Console.WriteLine( time.ToString() );
34 } // end Main
35 } // end class Time1Test
 
 The initial universal time is: 00:00:00
 The initial standard time is: 12:00:00 AM

 Universal time after SetTime is: 13:27:06
 Standard time after SetTime is: 1:27:06 PM

 After attempting invalid settings:
 Universal time: 00:00:00
 Standard time: 12:00:00 AM

Class Time1 contains three private instance variables of type int (Fig. 9.1, lines 57)hour, minute and secondthat represent the time in universal-time format (24-hour clock format, in which hours are in the range 023). Class Time1 contains public methods SetTime (lines 1116), ToUniversalString (lines 1923) and ToString (lines 2631). These methods are the public services or the public interface that the class provides to its clients.

In this example, class Time1 does not declare a constructor, so the class has a default constructor that is supplied by the compiler. Each instance variable implicitly receives the default value 0 for an int. Note that when instance variables are declared in the class body they can be initialized using the same initialization syntax as a local variable.

Method SetTime (lines 1116) is a public method that declares three int parameters and uses them to set the time. A conditional expression tests each argument to determine whether the value is in a specified range. For example, the hour value (line 13) must be greater than or equal to 0 and less than 24, because universal-time format represents hours as integers from 0 to 23 (e.g., 1 PM is hour 13 and 11 PM is hour 23; midnight is hour 0 and noon is hour 12). Similarly, both minute and second values (lines 14 and 15) must be greater than or equal to 0 and less than 60. Any out-of-range values are set to 0 to ensure that a Time1 object always contains consistent datathat is, the object's data values are always kept in range, even if the values provided as arguments to method SetTime are incorrect. In this example, 0 is a consistent value for hour, minute and second.

A value passed to SetTime is a correct value if that value is in the allowed range for the member it is initializing. So, any number in the range 023 would be a correct value for the hour. A correct value is always a consistent value. However, a consistent value is not necessarily a correct value. If SetTime sets hour to 0 because the argument received was out of range, then SetTime is taking an incorrect value and making it consistent, so the object remains in a consistent state at all times. In this case, the application might want to indicate that the object is incorrect. In Chapter 12, Exception Handling, you will learn techniques that enable your classes to indicate when incorrect values are received.

Software Engineering Observation 9 1

Methods and properties that modify the values of private variables should verify that the intended new values are proper. If they are not, they should place the private variables in an appropriate consistent state.

Method ToUniversalString (lines 1923) takes no arguments and returns a string in universal-time format, consisting of six digitstwo for the hour, two for the minute and two for the second. For example, if the time were 1:30:07 PM, method ToUniversalString would return 13:30:07. The return statement (lines 2122) uses static method Format of class string to return a string containing the formatted hour, minute and second values, each with two digits and, where needed, a leading 0 (specified with the D2 format specifierwhich pads the integer with 0s if it has less than two digits). Method Format is similar to the string formatting in method Console.Write, except that Format returns a formatted string rather than displaying it in a console window. The formatted string is returned by method ToUniversalString.

Method ToString (lines 2631) takes no arguments and returns a string in standard-time format, consisting of the hour, minute and second values separated by colons and followed by an AM or PM indicator (e.g., 1:27:06 PM). Like method ToUniversalString, method ToString uses static string method Format to format the minute and second as two-digit values with leading 0s, if necessary. Line 29 uses a conditional operator (?:) to determine the value for hour in the stringif the hour is 0 or 12 (AM or PM), it appears as 12otherwise, the hour appears as a value from 1 to 11. The conditional operator in line 30 determines whether AM or PM will be returned as part of the string.

Recall from Section 7.4 that all objects in C# have a ToString method that returns a string representation of the object. We chose to return a string containing the time in standard-time format. Method ToString is called implicitly when an object's value is output with a format item in a call to Console.Write. Remember that to enable objects to be converted to their string representations, we need to declare method ToString with keyword overridethe reason for this will become clear when we discuss inheritance in Chapter 10.

Using Class Time1

As you learned in Chapter 4, each class you declare represents a new type in C#. Therefore, after declaring class Time1, we can use it as a type in declarations such as

Time1 sunset; // sunset can hold a reference to a Time1 object

The Time1Test application class (Fig. 9.2) uses class Time1. Line 10 creates a Time1 object and assigns it to local variable time. Note that new invokes class Time1's default constructor, since Time1 does not declare any constructors. Lines 1317 output the time, first in universal-time format (by invoking time's ToUniversalString method in line 14), then in standard-time format (by explicitly invoking time's ToString method in line 16) to confirm that the Time1 object was initialized properly.

Line 20 invokes method SetTime of the time object to change the time. Then lines 2125 output the time again in both formats to confirm that the time was set correctly.

To illustrate that method SetTime maintains the object in a consistent state, line 28 calls method SetTime with invalid arguments of 99 for the hour, minute and second. Lines 2933 output the time again in both formats to confirm that SetTime maintains the object's consistent state, then the application terminates. The last two lines of the application's output show that the time is reset to midnightthe initial value of a Time1 objectafter an attempt to set the time with three out-of-range values.

Notes on the Time1 Class Declaration

Consider several issues of class design with respect to class Time1. The instance variables hour, minute and second are each declared private. The actual data representation used within the class is of no concern to the class's clients. For example, it would be perfectly reasonable for Time1 to represent the time internally as the number of seconds since midnight or the number of minutes and seconds since midnight. Clients could use the same public methods and properties to get the same results without being aware of this. (Exercise 9.5 asks you to represent the time as the number of seconds since midnight and show that there is indeed no change visible to the clients of the class.)

Software Engineering Observation 9 2

Classes simplify programming because the client can use only the public members exposed by the class. Such members are usually client oriented rather than implementation oriented. Clients are neither aware of, nor involved in, a class's implementation. Clients generally care about what the class does but not how the class does it. (Clients do, of course, care that the class operates correctly and efficiently.)

Software Engineering Observation 9 3

Interfaces change less frequently than implementations. When an implementation changes, implementation-dependent code must change accordingly. Hiding the implementation reduces the possibility that other application parts will become dependent on class-implementation details.



Controlling Access to Members

Preface

Index

    Introduction to Computers, the Internet and Visual C#

    Introduction to the Visual C# 2005 Express Edition IDE

    Introduction to C# Applications

    Introduction to Classes and Objects

    Control Statements: Part 1

    Control Statements: Part 2

    Methods: A Deeper Look

    Arrays

    Classes and Objects: A Deeper Look

    Object-Oriented Programming: Inheritance

    Polymorphism, Interfaces & Operator Overloading

    Exception Handling

    Graphical User Interface Concepts: Part 1

    Graphical User Interface Concepts: Part 2

    Multithreading

    Strings, Characters and Regular Expressions

    Graphics and Multimedia

    Files and Streams

    Extensible Markup Language (XML)

    Database, SQL and ADO.NET

    ASP.NET 2.0, Web Forms and Web Controls

    Web Services

    Networking: Streams-Based Sockets and Datagrams

    Searching and Sorting

    Data Structures

    Generics

    Collections

    Appendix A. Operator Precedence Chart

    Appendix B. Number Systems

    Appendix C. Using the Visual Studio 2005 Debugger

    Appendix D. ASCII Character Set

    Appendix E. Unicode®

    Appendix F. Introduction to XHTML: Part 1

    Appendix G. Introduction to XHTML: Part 2

    Appendix H. HTML/XHTML Special Characters

    Appendix I. HTML/XHTML Colors

    Appendix J. ATM Case Study Code

    Appendix K. UML 2: Additional Diagram Types

    Appendix L. Simple Types

    Index



    Visual C# How to Program
    Visual C# 2005 How to Program (2nd Edition)
    ISBN: 0131525239
    EAN: 2147483647
    Year: 2004
    Pages: 600

    Flylib.com © 2008-2020.
    If you may any questions please contact us: flylib@qtcs.net