FIT9131
Week 8
Programming Foundations FIT9131
Encapsulation, class variables and methods, scoping
1
Week 8
FIT9131
Week 8
Lecture outline
• Good Program Design principles • Encapsulation
• Information hiding
• Access modifiers – public and private • Scoping – block and class scope
• “Masking” and name conflicts • Class variables
• Class methods
• Constants
• Deadly Error : Null pointer exception 2
FIT9131
Week 8
Example :
Person
class
Person
name: String
age: int isStudent: boolean
Person()
Person(String, int, boolean) getName(): String
getAge(): int
getStatus(): boolean setName(String): boolean setAge(int) : boolean setStatus(boolean) : boolean validName(string): boolean validAge(int): boolean display()
Attributes
What does this Class Diagram tell (and not tell) you??
(fields)
Behaviours
(methods)
3
FIT9131
Week 8
Encapsulation
display
setName age getAge name
isStudent
setStatus validName getName validAge
An object’s fields are “encapsulated” together with its behaviour
setAge
4
constructors
getStatus
Encapsulation is the grouping of related ideas into one unit, which can thereafter be referred to by a single name (Page- Jones, 2000)
FIT9131
Week 8
An object should hides its fields
age
name
age
aPerson (an object)
5
isStudent
name
validName
validName
validAge
validAge
The fields (and some methods) are typically hidden to the outside world.
FIT9131 Week 8
Interfaces (behavior) of an object
How do we know what we can ask an object to do?
The object has a public interface that “advertises” what it can be asked to do. It also indicates how to use that interface.
What the outside world sees
is the object’s public interface. An object’s internal working is not relevant to the outside world.
setAge
display
display
getAge setStatus validAge getName
setName age Name
isStudent
validName
6
What can you see in the public interface for this object?
constructors
getStatus
FIT9131
Week 8
Communicating with an object : Message Passing
To find out the value of a field of an object (or to change that field) requires a request to the object. This is typically referred to as “sending a message“.
Message
getName
aPerson
name Age ……
7
Value (if any) returned as a result of sending the message
“Jack”
FIT9131
Week 8
Using value returned from a Message
In Java, the act of “sending a message” to an object is achieved by calling a method from an object’s public interface. For instance, in the previous example, we could write the following Java statements :
String bestFriend = aPerson.getName(); ✓
Why is the 2nd statement wrong?
8
String bestFriend = aPerson.name;
FIT9131
Week 8
Information hiding
The internals of a class should be hidden from other classes.
To use a class a programmer only needs to know what an object can do (interface), not how it does it (implementation).
Two aspects to consider when using a class :
• no need to know the internals – principles of abstraction and modularisation
• not allowed to know the internals – ensures independence of classes
9
FIT9131
Week 8
Information hiding
Information hiding increases the level of independence.
Independence of modules (classes, methods, etc) is very important for development of large systems and maintenance of systems in general.
10
FIT9131
Week 8
Access modifiers
11
Access modifiers specify which other classes are allowed to access fields and methods in a class, i.e. which fields and methods are visible from outside the class declaration. We use these to control the scope of fields and methods.
Local variables do not have access modifiers. Local variables are defined inside a method. Their scopes are always confined to the body of the defining method. In other words, no other methods can access them.
FIT9131
Week 8
Attributes Versus Local Variables
12
Whenever possible, try to reduce the number of attributes (fields) of a class to a minimum. If there are values which need to be shared among different methods, try to do so via the use of parameters (and local variables) and return value instead of using lots of attributes.
• by doing so, we limit the scope of variables, which makes the methods more independent and the program more maintainable
FIT9131
Week 8
versus
A field, constructor or method can be declared to be public or private.
public — accessible within the class and to other classes.
private — accessible only within the same class.
public
private
13
FIT9131
Week 8
Should
In general, fields should not be public.
This prevents the fields from being accidentally
modified by other objects.
To access these private fields, use the appropriate
accessor/mutator methods.
The access mode of a field must be explicitly
specified.
fields
be public or private?
14
FIT9131
Week 8
Should
Only methods that are intended for use by other classes should be public. This allows these methods to be accessible (via the object’s public interface) by other objects.
Methods which are used only internally (by the object itself) should be declared as private.
The access mode of a method must be explicitly specified.
methods
be public or private?
15
FIT9131
Week 8
Why are private methods useful?
Any method that no other class needs to know about should be declared private. For example, the validAge() method in the Person class.
Private methods are generally used to make implementation of a class easier to read – by reducing the public interface.
We try to restrict access to variables and methods as much as possible, to increase the reliability of our programs.
When testing a class, make all methods public. After testing, make the “private methods” private again.
16
FIT9131 Week 8
Person
class
: improved class diagram
Person
– name: String
– age: int
– isStudent: boolean
+ Person()
+ Person(String, int, boolean) + getName(): String
+ getAge(): int
+ getStatus(): boolean
+ setName(String): boolean
+ setAge(int) : boolean
+ setStatus(boolean) : boolean – validName(string): boolean – validAge(int): boolean
+ display()
Visibility:
– private
+ public
17
FIT9131 Week 8
Review: fields, parameters and local variables
Definition
Scope
Lifetime
fields
Defined outside constructors and methods
Within any methods or constructors of the class (if private) in which they are defined
Exist while their object exists
parameters
Defined in the header or the method or constructor
Within the body of the method in which they are defined
Exist while the method or constructor executes
local variables
Defined within the body of a method or constructor
Within the block in which they are defined, starting from the line where they are defined
Exist while the method or constructor executes
18
FIT9131
Week 8
Scoping
19
The scope of a method or a variable is the part of a program that can access it. We should limit the scope of variables and methods as much as possible, to reduce the chance of error in a program.
2 kinds of scoping that we have already discussed in programs are:
• class scope • block scope
FIT9131
Week 8
Class scope
20
All private fields and private methods have class scope. This means that any statement inside the class declaration can access them. The class declaration is delimited by the set of braces around the entire body of the class.
Any field can be referred to or modified by any statement, in any method, in the entire class.
Any method can be called by any statement, in any method, in the entire class.
FIT9131
Week 8
Block scope
A block is an area of a method delimited by a set of braces { }. Note that the body of a method is implicitly a block.
A variable declared inside a block has block scope. It exists only inside that block, and only while that block is being executed. Statements outside that block cannot reference it. When the block of code finishes executing, the variables declared inside that block cease to exist.
21
FIT9131
Week 8
Block scope
Some examples of blocks are:
• the body of a method
• a compound statement that is the consequent or alternative of an if statement
• a compound statement that is the body of a loop A block can be placed anywhere in the code. This is
commonly done to restrict the scope of a variable.
22
FIT9131
Week 8
Common Error : Referencing a variable outside its block
public String inputStudentName() {
boolean valid = false;
Scanner input = new Scanner(System.in); while (!valid)
{
variable declared inside while loop
Scope of
newStudent
String newStudent = “”; System.out.println(“What is your name?”); newStudent = input.nextLine();
valid = validName(newStudent);
}
System.out.println(“Welcome: ” + newStudent);
23
return newStudent; }
This produces a compilation error, such as :
cannot find symbol – variable newStudent
FIT9131
Week 8
Correct version of
inputStudentName
public String inputStudentName() {
boolean valid = false;
String newStudent = “”;
Scanner input = new Scanner(System.in); while (!valid)
{
return newStudent;
}
24
✓
✓
()
variable declared outside while loop
Scope of
newStudent
System.out.println(“What is your name?”); newStudent = input.nextLine();
valid = validName(newStudent);
}
System.out.println(“Welcome: ” + newStudent);
FIT9131
Week 8
Block scope and local variables
The entire body of a method is a block. A variable defined inside the body of a method is called a local variable (e.g. the variables valid, input and newStudent on the previous slide).
A variable declared at the beginning of a method has a scope of the entire body of the method. No other method can refer to that variable.
A variable can be declared anywhere inside a method. Its scope is from the point where it is declared to the end of its block.
25
FIT9131
Week 8
Variables with the same name
If we have two variables with the same name and the same scope, we get a syntax error.
If we declare a local variable with the same name as an existing field or an existing variable that is local to another method, there is no problem as far as the compiler is concerned (although it may be confusing to humans!).
Example: a local variable in one method that is passed to another method with a formal parameter of the same name.
26
FIT9131
Week 8
Formal parameter and actual argument with same name
public boolean setName(String aName) {
if (validName(aName))
{
name = aName; return true;
}
return false;
}
private boolean validName(String aName) {
return (aName.trim().length() != 0); }
27
No problems here – the 2 parameters have their own scope
FIT9131
Week 8
Masked or hidden variables
If more than one variable with the same name is accessible from a part of a program, a mention of that name will access the one that is closest in scope. This can cause unintended effects.
Eg. Consider the Person class from the earlier example, which had an attribute called “name”. If we now use declare another variable using that same name in another method :
private String asString()
{
String name = “???”;
return (“Name is ” + name + ” and age is ” + age +
}
28
” status is: ” +
(isStudent ? “Student” : “Not a Student”);
Are these referring to the attribute, or the local variable?
FIT9131
Week 8
Using two variables of the same name with different scopes
field { or
parameter?
age = age;
If we use a formal parameter which has the same name as a field in the same method, things can get a little confusing.
public boolean setAge(int age) {
if (validAge(age))
What is wrong with this code?
Formal parameter parameter?
return true;
}
field or
return false; }
29
FIT9131
Week 8
Using two variables of the same name with different scopes
It is possible (but not really advisable) to solve the confusion (& problem) with the special “this” keyword. We have seen this before (week 4).
public boolean setAge(int age) {
if (validAge(age))
{
this.age = age;
return true;
}
A better solution is : use different names!
field
30
return false; }
Formal parameter
FIT9131
Week 8
Using different variables names to avoid scoping confusion
The previous confusion can be easily avoided by using different parameter names.
field
public boolean setAge(int newAge) {
if (validAge(newAge))
{
age = newAge;
return true; }
31
return false;
}
Formal parameter
FIT9131
Week 8
this
this is a keyword that means “the current object”, i.e. the one that is currently in control, which has been asked to invoke this method.
It is possible to write this in front of anything with class scope, i.e. any field or method name but it is really not necessary unless you need to clarify the scope.
public void setAllFields(String aName, int anAge,
boolean aStudentStatus)
{
this.name = aName;
this.age = anAge; this.isStudent = aStudentStatus;
}
32
not really necessary, since there is no ambiguity here
FIT9131
Week 8
Calling another method in the same class
You could also write this in front of any call to another method in the same class, if you wanted to be pedantic about always putting the name of an object in front of a call. The object you are asking to invoke the method is the current object.
public void display() {
System.out.println(this.asString()); }
33
again, not really necessary
FIT9131
Week 8
Fields
An object is an instance of a class.
An object has fields.
Each object instantiated from the class has its own set of fields.
Person friend = new Person();
Person brother = new Person(“Ben”, 15, true); Person sister = new Person(“Mel”, 18, true); Person father = new Person(“Tom”, 45, false);
In other words, a field cannot exist unless an object has been instantiated from the class.
34
FIT9131
Week 8
Example : Four
Person
objects
each object has its own set of fields, with possibly different values
“Ben”, 15, true
brother
friend
“”, 0, false
“Mel”, 18, true
35
sister
father
“Tom”, 45, false
FIT9131
Week 8
Class variables
Sometimes we want a variable to exist even if no objects have been created. For example, we might want to keep a count of how many objects of a certain type currently exist.
For this, we can use a class variable. It belongs to the class itself, and every object has access to it.
A class variable is declared in Java as static. It is created and initialised when the class is loaded into memory – before any of its objects has been created.
36
FIT9131
Week 8
Example : using a class variable to keep a count of the number of objects created
public class Person
{
// normal instance variables (fields)
private String name;
private int age;
private boolean isStudent;
// example of a class variable
private static int numberOfPersons = 0;
… }
note that this is initialised when it is declared (ie. not in the constructor)
37
FIT9131 Week 8
The
Person
class constructor
Example : to count the number of Person objects that have been created, we have to increment the counter each time a new Person object is created. The best place to do this is in the constructor(s) of the class.
public Person(String aName, int anAge, boolean aStudentStatus) {
age = anAge;
name = aName;
isStudent = aStudentStatus; numberOfPersons++;
}
38
what would happen if
numberOfperson
was declared as a normal field?
FIT9131
Week 8
Class variables
private int numberOfPersons
is instance of
is instance of
is instance of
39
FIT9131
Week 8
Problem : Accessing a private class variable in an object
A class variable can be accessed through any object instantiated from the class – unless it is private.
public int testGetNumberOfPersons() // from another class {
Person friend = new Person();
Person brother = new Person(“Ben”, 15, true);
Person sister = new Person(“Mel”, 18, true);
Person father = new Person(“Tom”, 45, false);
return friend.numberOfPersons;
}
40
This produces a compilation error:
number0fPersons has private access
FIT9131
Week 8
Solution : Class methods
To allow external objects to access a (private) class variable’s value, we need to provide a public class method to return its value.
In this case, we provide a public static method called getNumberOfPersons to return the value of the private class variable numberOfPersons.
public static int getNumberOfPersons() // from Person class {
return numberOfPersons;
}
41
example of a “class method”
FIT9131
Week 8
Accessing the class variable using the class
In the testGetNumberOfPersons method, we can now send a message to the class Person to invoke the getNumberOfPersons method:
public int testGetNumberOfPersons() // from another class {
Person friend = new Person();
Person brother = new Person(“Ben”, 15, true); Person sister = new Person(“Mel”, 18, true); Person father = new Person(“Tom”, 45, false); return Person.getNumberOfPersons();
}
42
✓
FIT9131
Week 8
Accessing a class variable using an instance of the class
We could also ask any of the existing objects to invoke that class method:
public int testGetNumberOfPersons() // from another class {
Person friend = new Person();
Person brother = new Person(“Ben”, 15, true); Person sister = new Person(“Mel”, 18, true); Person father = new Person(“Tom”, 45, false); return father.getNumberOfPersons();
}
43
✓
FIT9131
Week 8
Another class method example
Sometimes a class variable or class method is created because it may be inconvenient to have to create an instance in order to perform some common operation.
Example: The methods in the Math class in Java are all class methods.
public double calculateDiagonalOfRectangle()
{
return Math.sqrt((length * length)+ (width * width));
}
Note that this is a class, not an object
44
example of a class method
FIT9131
Week 8
Example of a class
The Math class also has some class variables, e.g. PI.
public void displayPi()
{
System.out.println(Math.PI); }
variable
45
example of a class variable
FIT9131
Week 8
Constants
Sometimes a class or a method wants a variable to have a value that cannot be changed. This is called a constant.
In order to make sure that the value cannot be changed, the variable is declared as final.
Constants must be initialised at the time of declaration. Constants are named using all capital letters (see Java
coding standards).
Examples :
final int NUMBER_OF_PLACES = 10; final String HEADING = “Monash”; final double PI = 3.142;
46
FIT9131 Week 8
Example : Calculating the area of a circle
public void printAreaOfCircle()
{
final double PI = 3.142;
double radius = 2.5; System.out.println(“Radius of circle is ”
+ radius + ” metres”);
System.out.println(“Area is ”
}
47
+ PI * radius * radius
+ ” square metres”);
declaring a constant
using a constant
FIT9131
Week 8
Objects and their existences
Important : an object can only be used if it exists!
New programmers (and even seasoned programmers) often make the mistake of referring to an object when it has not been created. This will lead to a memory error, commonly referred to as “Null Pointer Exception” in many programming languages (including Java) – typically crashing the program.
This is particularly common when using arrays of objects – since these objects do not really have names assigned to them, and yet can be assessed via the array’s indices.
48
FIT9131
Week 8
Declaring versus Creating Objects
Important : declaring an object is not the same as creating it!
Declaring an object : Person aPerson;
if we now try to execute something like aPerson.getName() immediately, the program will crash!
Now that the object is created, we can call aPerson.getName()
✓
Creating an object :
aPerson = new Person(“david”, 25, true);
49
FIT9131
Week 8
Example : Creating an array of objects
An array of objects is actually an array of references to objects, eg :
Person[] family = new Person[6];
null
null
null
null
null
null
50
family
Important : These references have not been initialized. They have null values. We
have not yet created the individual Person objects.
FIT9131
Week 8
Null pointer
When an object is created, its name is a reference to the object.
Person aPerson = new Person();
“Unknown“
0
false
aPerson
A null pointer is an address that is all zeroes, i.e. it is not a real address and points to nothing. It is still recognised as being of a certain type.
51
Eg : aPerson = null;
aPerson
00000000
FIT9131
Week 8
Error
Common programming error : trying to put values into objects that do not yet exist. Eg :
NullPointerException
public void testPersonArray()
{
Person[] family = new Person[6];
creating an array which can hold up to 6 Person object – none of these objects had been created yet.
Scanner input = new Scanner(System.in);
for (int position = 0; position < family.length; position++) {
System.out.print("Name of family member: ");
family[position].setName(input.next()); }
null
null
null
null
null
null
}
52
trying to refer to a non-existing object!!!
family
FIT9131
Week 8
An array of objects
For each element of the array, we need to create an object that it references, before using them.
family[0]
family
family[5]
53
FIT9131 Week 8
Creating the objects for the array
public void testPersonArray()
{
Person[] family = new Person[6];
for (int position = 0; position < family.length; position++) family[position] = new Person();
Scanner input = new Scanner(System.in);
for (int position = 0; position < family.length; position++)
{
System.out.print("Name of family member: ");
family[position].setName(input.next()); }
System.out.println();
for (int position = 0; position < family.length; position++)
System.out.println(family[position].getName());
}
54
creating the array objects
now ok