2. When the app executes, another compiler (known as the just-in-time compiler
4.5 Instance Variables and Properties
In Chapter 3, we declared all of an app’s variables in theMainmethod. Variables declared in the body of a method are known aslocal variablesand can be used only in that method.
When a method terminates, the values of its local variables are lost. Recall from Section 4.2 that an object has attributes that are carried with it as it’s used in an app. Such attributes exist before a method is called on an object and after the method completes execution.
Attributes are represented as variables in a class declaration. Such variables are called fieldsand are declaredinsidea class declaration butoutsidethe bodies of the class’s method declarations. When each object of a class maintains its own copy of an attribute, the field that represents the attribute is also known as an instance variable—each object (instance) of the class has a separate instance of the variable. In Chapter 10, we discuss another type of field called astaticvariable, where all objects of the same class share one variable.
A class normally contains one or more properties that manipulate the attributes that belong to a particular object of the class. The example in this section demonstrates a
GradeBook class that contains acourseName instance variable to represent a particular
GradeBookobject’s course name, and aCourseNameproperty to manipulatecourseName. GradeBookClass with an Instance Variable and a Property
In our next app (Figs. 4.7–4.8), classGradeBook(Fig. 4.7) maintains the course name as an instance variable so that it can be used or modified at any time during an app’s execu- tion. The class also contains one method—DisplayMessage (lines 24–30)—and one
System.Console.WriteLine( "Please enter the course name:" );
4.5 Instance Variables and Properties 117
property—CourseName (line 11–21). Recall from Chapter 2 that properties are used to manipulate an object’sattributes. For example, in that chapter, we used aLabel’sText property to specify the text to display on theLabel. In this example, we use a property in code rather than in thePropertieswindow of the IDE. To do this, we first declare a prop- erty as a member of theGradeBookclass. As you’ll soon see, theGradeBook’sCourseName property can be used to store a course name in aGradeBook(in instance variablecourse-
Name) or retrieve the GradeBook’s course name (from instance variable courseName).
MethodDisplayMessage—which now specifies no parameters—still displays a welcome message that includes the course name. However, the method now uses theCourseName property to obtain the course name from instance variablecourseName.
A typical instructor teaches more than one course, each with its own course name.
Line 8 declarescourseNameas a variable of typestring. Line 8 is a declaration for an instance variable, because the variable is declared in the class’s body (lines 7–31) but out- side the bodies of the class’s method (lines 24–30) and property (lines 11–21). Every instance (i.e., object) of classGradeBookcontains one copy of each instance variable. For 1 // Fig. 4.7: GradeBook.cs
2 // GradeBook class that contains a private instance variable, courseName, 3 // and a public property to get and set its value.
4 using System;
5
6 public class GradeBook 7 {
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
23 // display a welcome message to the GradeBook user 24 public void DisplayMessage()
25 {
26 // use property CourseName to get the
27 // name of the course that this GradeBook represents 28 Console.WriteLine( "Welcome to the grade book for\n{0}!",
29 ); // display property CourseName
30 } // end method DisplayMessage 31 } // end class GradeBook
Fig. 4.7 | GradeBookclass that contains aprivateinstance variable,courseName, and a
publicproperty togetandsetits value.
private string courseName; // course name for this GradeBook // property to get and set the course name
public string CourseName {
get {
return courseName;
} // end get set
{
courseName = value;
} // end set
} // end property CourseName
CourseName
example, if there are twoGradeBookobjects, each object has its own copy ofcourseName. All the methods and properties of classGradeBook can directly manipulate its instance variablecourseName, but it’s considered good practice for methods of a class to use that class’s properties to manipulate instance variables (as we do in line 29 of methodDis-
playMessage). The software engineering reasons for this will soon become clear.
Access Modifierspublicandprivate
Most instance-variable declarations are preceded with the keywordprivate(as in line 8).
Likepublic, keywordprivateis an access modifier. Variables, properties or methods de- clared with access modifierprivateare accessibleonlyto members (such as properties and methods) of the class in which they’re declared. Thus, variablecourseNamecan be used onlyin propertyCourseNameand methodDisplayMessageof classGradeBook.
Declaring instance variables with access modifierprivateis known asinformation hiding(orencapsulation). When an app creates (instantiates) an object of classGrade-
Book, variablecourseNameis encapsulated (hidden) in the object and can be accessed only by members of the object’s class.
Setting and Getting the Values ofprivateInstance Variables
How can we allow a program to manipulate a class’sprivateinstance variables but ensure that they remain in a valid state? We need to providecontrolledways for programmers to
“get” (i.e., retrieve) the value in an instance variable and “set” (i.e., modify) the value in an instance variable. Although you can define methods likeGetCourseNameandSetCourse-
Name, C# properties provide a more elegant solution. Next, we show how to declare and use properties.
GradeBookClass with a Property
The GradeBook class’s CourseName property declaration is located in lines 11–21 of Fig. 4.7. The property begins in line 11 with an access modifier (in this case,public), fol- lowed by the type that the property represents (string) and the property’s name (Course-
Name). Properties use thesamenaming conventions as methods and classes.
Properties containaccessorsthat handle the details of returning and modifying data.
A property declaration can contain agetaccessor, asetaccessor or both. Thegetaccessor (lines 13–16) enables a client to read the value ofprivateinstance variablecourseName; thesetaccessor (lines 17–20) enables a client to modifycourseName.
Software Engineering Observation 4.2
Precede every field and method declaration with an access modifier. Generally, instance variables should be declaredprivate and methods and properties should be declared
public. If the access modifier is omitted before a member of a class, the member is implicitly declaredprivate. We’ll see that it’s appropriate to declare certain methods
private, if they will be accessed only by other methods of the class.
Software Engineering Observation 4.3
Declaring the instance variables of a class asprivateand the methods and properties of the class aspublicfacilitates debugging, because problems with data manipulations are localized to the class’s methods and properties, since theprivateinstance variables are accessible only to these methods and properties.
4.5 Instance Variables and Properties 119
After defining a property, you can use it like a variable in your code. For example, you can assign a value to a property using the=(assignment) operator. This executes the prop- erty’sset accessor to set the value of the corresponding instance variable. Similarly, refer- encing the property to use its value (for example, to display it on the screen) executes the code in the property’sgetaccessor to obtain the correspondinginstance variable’svalue. We show how to use properties shortly. By convention, we name each property with the capitalized name of the instance variable that it manipulates (e.g.,CourseNameis the property that rep- resents instance variablecourseName)—C# is case sensitive, so these are distinct identifiers.
getandsetAccessors
Let us look more closely at propertyCourseName’sgetandsetaccessors (Fig. 4.7). The
getaccessor (lines 13–16) begins with the identifier get and its body is delimited by braces. The accessor’s body contains areturnstatement, which consists of the keyword
returnfollowed by an expression. The expression’s value is returned to the client code that uses the property. In this example, the value ofcourseNameis returned when the property
CourseNameis referenced. For example, in the following statement
the expressiongradeBook.CourseName(wheregradeBookis an object of classGradeBook) executes propertyCourseName’sgetaccessor, which returns the value of instance variable
courseName. That value is then stored in variabletheCourseName. PropertyCourseName can be usedas simply as if it were an instance variable. The property notation allows the client to think of the property as the underlying data. Again, the client cannot directly ma- nipulate instance variablecourseNamebecause it’sprivate.
Thesetaccessor (lines 17–20) begins with the identifiersetand its body is delimited by braces. When the propertyCourseNameappears in an assignment statement, as in
the text"CS100 Introduction to Computers"is assigned to thesetaccessor’s contextual keyword namedvalueand thesetaccessor executes. Note thatvalueisimplicitlydeclared and initialized in thesetaccessor—it’s a compilation error to declare a local variableval- uein this body. Line 19 stores the contents ofvaluein instance variablecourseName. A
setaccessor does not return any data when it completes its task.
The statements inside the property in lines 15 and 19 (Fig. 4.7) each accesscourse-
Name even though it was declared outside the property. We can use instance variable
courseNamein the methods and properties of classGradeBook, becausecourseNameis an instance variable of the class.
Using PropertyCourseNamein MethodDisplayMessage
MethodDisplayMessage(lines 24–30 of Fig. 4.7) does not receive any parameters. Lines 28–29 output a welcome message that includes the value of instance variablecourseName. We do not referencecourseNamedirectly. Instead, we access propertyCourseName(line 29), which executes the property’sgetaccessor, returning the value ofcourseName. GradeBookTestClass That Demonstrates ClassGradeBook
Class GradeBookTest (Fig. 4.8) creates a GradeBook object and demonstrates property
CourseName. Line 11 creates aGradeBookobject and assigns it to local variablemyGrade-
string theCourseName = gradeBook.CourseName;
gradeBook.CourseName = "CS100 Introduction to Computers";
Book. Lines 14–15 display the initial course name using the object’sCourseNameproper- ty—this executes the property’sgetaccessor, which returns the value ofcourseName.
The first line of the output shows an empty name (marked by single quotes, ''). Unlike local variables, which are not automatically initialized, every field has adefault ini- tial value—a value provided by C# when you do not specify the initial value. Thus, fields arenotrequired to be explicitly initialized before they’re used in an app—unless they must be initialized to valuesotherthan their default values. The default value for an instance variable of typestring(likecourseName) isnull. When you display astringvariable that contains the valuenull, no text is displayed on the screen.
Line 18 prompts the user to enter a course name. Line 19 assigns the course name entered by the user to objectmyGradeBook’sCourseNameproperty. When a value is assigned toCourseName, the value specified (which is returned byReadLinein this case) is assigned to implicit parametervalueofCourseName’ssetaccessor (lines 17–20, Fig. 4.7). Then param- eter value is assigned by the set accessor to instance variable courseName (line 19 of 1 // Fig. 4.8: GradeBookTest.cs
2 // Create and manipulate a GradeBook object.
3 using System;
4
5 public class GradeBookTest 6 {
7 // Main method begins program execution 8 public static void Main( string[] args )
9 {
10 // create a GradeBook object and assign it to myGradeBook 11 GradeBook myGradeBook = new GradeBook();
12
13 // display initial value of CourseName
14 Console.WriteLine( "Initial course name is: '{0}'\n",
15 );
16
17 // prompt for and read course name
18 Console.WriteLine( "Please enter the course name:" );
19
20 Console.WriteLine(); // output a blank line 21
22 // display welcome message after specifying course name 23
24 } // end Main
25 } // end class GradeBookTest
Initial course name is: '' Please enter the course name:
CS101 Introduction to C# Programming Welcome to the grade book for
CS101 Introduction to C# Programming!
Fig. 4.8 | Create and manipulate aGradeBookobject.
myGradeBook.CourseName
myGradeBook.CourseName = Console.ReadLine(); // set CourseName
myGradeBook.DisplayMessage();