3. Methods and Encapsulation in Java
3.1 Scope of Variables
The scope defines lifespan of a variable. There are four different scopes in Java:
- Local variables
- Method parameters
- Instance variables
- Class variables
3.1.1 Local Variables
Variables defined within a method. These are used mainly to store immediate results of a calculation. They have the shortest life span. In the following code, a local variable avg is defined within the method getAverage():
class Student { private double marks1, marks2, marks3; //instance variables private double maxMarks = 100; //instance variable public double getAverage() { double avg= 0; //local variable avg avg= ((marks1 + marks2 + marks3) / (maxMarks*3)) * 100; //avg inaccessible outside getAverage return avg; } }
The scope of a variable can be reduced to a for block or an if statement within a method:
public void localVariableInLoop() { for (int ctr= 0; ctr < 5; ++ctr) { //ctr defined within the loop System.out.println(ctr); } System.out.println(ctr);//ctr inaccessible outside the loop, code would not compile }
public double getAverage() { if (maxMarks > 0) { double avg = 0; //avg local to block avg = (marks1 + marks2 + marks3)/(maxMarks*3) * 100; return avg; } else { avg = 0; //avg cannot be accessed from here, code would not compile return avg; } }
3.1.2 Method Parameters
Variables that accept values within a method those are accessible only in the method that defines them.
class Phone { private boolean tested; public void setTested(boolean val) { tested = val; //accessible only in setTested method } public boolean isTested() { val= false; //this line won’t compile return tested; } }
The scope of a method parameter may be as long as that of a local variable, or longer, but it can never be shorter.
3.1.3 Instance Variables
An instance variable is available for the life of an object. Declared inside the class, outside of the methods and accessible to all nonstatic methods within the class.
class Phone { private boolean tested; //instance variable public void setTested(boolean val) { tested= val; //tested is accessible here } public boolean isTested() { return tested; //tested is accessible here } }
The scope of instance variables is longer than that of local variables or method parameters.
3.1.4 Class Variables
A class variable is defined by using the keyword static. It belongs to a class and not to individual objects of the class, therefore it is shared across all objects.
package com.mobile; class Phone { static boolean softKeyboard= true; //class variable } package com.mobile; class TestPhone { public static void main(String[] args) { Phone.softKeyboard= false; //accessing variable by using class name Phone p1 = new Phone(); Phone p2 = new Phone(); System.out.println(p1.softKeyboard);//accessing variable by object name System.out.println(p2.softKeyboard); p1.softKeyboard = true; System.out.println(p1.softKeyboard); System.out.println(p2.softKeyboard); } }
A class variable can be changed using the name of the class or an object.
3.1.5. Overlapping Variable Scopes
Different local variables can have different scopes. The scope of local variables may be shorter, equal or as long as the scope of method parameters. Local variables can have a shorter scope if declared in a sub-block in a method.
In order to prevent conflicts with variable names, some rules are necessary:
• A static variable cannot be defined with the same name of an instance variable within the same class.
• Local variables and method parameters cannot use the same name.
3.2. Object’s Life Cycle
An object’s life cycle lasts from its creation until it goes out of its scope or is no longer referenced by a variable. When an object is accessible, it can be referenced by a variable and can be used by calling its methods and accessing its variables.
3.2.1. An Object is born
An object is created when the keyword new is used.
class Person {} class ObjectLifeCycle { Person person; //declaring only a reference }
class ObjectLifeCycle2 { Person person = new Person();//declaring and initializing a person type variable. }
When an unreferenced object is created, it only executes the relevant constructors of the class, but it cannot be accessed using any reference variable.
class ObjectLifeCycle2 { Person person = new Person(); // unreferenced object ObjectLifeCycle2() { new Person(); } }
3.2.2. Object is Accessible
Once an object is created, it remains accessible until it goes out of scope or its reference variable is explicitly set to null. Also if a reference variable gets reassigned to another object, the previous object becomes inaccessible.
class ObjectLife1 { public static void main(String args[]) { Exam myExam = new Exam(); //Object created myExam.setName("OCA Java Programmer 1"); myExam = null; //reference set to null myExam = new Exam(); //another object creation myExam.setName("PHP"); } }
After the reference variable gets assigned to null in the previous example, the first object is considered garbage by Java.
3.2.3. Object is Inaccessible
An object can become inaccessible if it can no longer be referenced by any variable, if it goes out of scope, if an object’s reference variable is assigned an explicit null value or if it is reinitialized.
When an object can no longer be accessed it is marked as eligible to be garbage collected. A user cannot control or determine the execution of a garbage collector as it is controlled by the Java Virtual Machine. It can be never be determined when a particular object will be garbage collected.
3.3. Create methods with arguments and return values
A method is a group of statements identified with a name. Methods are used to define the behavior of an object. A method can perform different functions:
3.3.1. Return type of a method
A method may or may not return a value, a void method does not return a value, a method can return a primitive value or an object of any class. The return type can be any of the eight primitive types defined in Java, the name of any class or an interface.
A void method result cannot be assigned to a variable, in that case the code would not compile. The assigned variable must also be compatible with the returned value.
3.3.2. Method Parameters
Method parameters are the variables that appear in the definition of a method and specify the type and number of values that a method can accept. No limit exists on the number of parameters that can be put within a method, but it is not a good practice to use more than five or six. A parameter that can accept variable arguments can be defined with ellipsis (…). The ellipsis indicates that the method parameter may be passed as an array or multiple comma-separated values. It can only be done once per method and must be the last variable in the parameter list:
Public int daysOff(int… days){ Int daysOff = 0; for(int i = 0; i < days.length; i++ ) daysOff += days[i]; return daysOff; }
3.3.3. Return Statement
This statement is used to exit from a method, with or without a value. If a method returns a value, the return statement must be followed by a return value. Methods that do not return a value (void) are not required to define a return statement. The return statement must be the last statement to execute in a method, the compiler will fail to compile if there’s code after it:
void setNumber(double val){ return; val = 3; //return must be the last statement to execute } void setNumber2(double val){ if(val < 0) return; //return is the last statement to be executed else val++; }
In this scenario, the return statement is not the last statement, but it will be the last statement to execute when the parameter val is less than zero.
3.4. Create an overloaded method
Overloaded methods are methods with the same name, defined In the same class but with different argument lists.
For example the System.out.println() accepts different types of parameters:
int intVal = 10; boolean boolVal = false; String name = "eJava"; System.out.println(intVal); //prints an integer System.out.println(boolVal); //prints a boolean System.out.println(name); // prints a string
3.4.1. Argument list
The argument lists of an overloaded method can differ in terms of any of these options:
- Change in the number of parameters that are accepted
- Change in the types of parameters that are accepted
- Change in the positions of the parameters that are accepted (based on parameter type, not variable names)
double calcAverage(int marks1, double marks2) { return (marks1 + marks2)/2.0; } double calcAverage(int marks1, int marks2, int marks3) { return (marks1 + marks2 + marks3)/3.0; }
In the previous example the methods differ in the number of parameters.
class MyClass { double calcAverage(double marks1, int marks2) { return (marks1 + marks2)/2.0; } double calcAverage(int marks1, double marks2) { return (marks1 + marks2)/2.0; } public static void main(String args[]) { MyClass myClass = new MyClass(); myClass.calcAverage(2, 3); // compiler can’t determine method to use } }
Because int can be passed to a variable type of double, the values 2 and 3 can be passed to both methods, in this scenario the compilation fails.
3.4.2. Return type
Methods can’t be defined as overloaded if they only differ in their return types.
3.4.3. Access modifier
Methods can’t be defined as overloaded if they only differ in their access modifiers.
3.5. Constructors of a class
Constructors are methods that create and return an object of the class in which they are defined. They have the same name of the class where they are defined and they don’t specify a return type, not even void.
3.5.1. User defined constructors
If the author of the class defines a constructor it is known as user defined constructor. It can be used to assign default values to the variables of the class. If a return type is specified, Java will treat it as another method and not as a constructor.
class Employee { void Employee() { //return type specified, not a constructor System.out.println("not a Constructor "); } } class Office { public static void main(String args[]) { Employee emp = new Employee(); emp.Employee();// calling the Employee method with void return type } }
3.5.1.1. Initializer block
It is a block defined in a class that is not a part of any method. It gets executed for every object that is created for a class.
class example { { System.out.println("Initializer Block"); } }
3.5.2. Default constructor
In the absence of a user defined constructor, Java inserts a default constructor; it doesn’t accept method arguments and assigns default values to all the instance variables.
3.5.3. Overloaded constructors
Overloaded constructors can be defined in the same way as overloaded methods. Overloaded constructors can be called within other constructors by using the keyword this.
class Employee { String name; int age; Employee() { //no arg constructor this(null, 0); //invoking the other constructor } Employee(String newName, int newAge) { //constructor with 2 arguments name = newName; age = newAge; } }
Constructors cannot be called from any other method that is not a constructor of the class.
3.6. Accessing object fields
3.6.1. What is an object field?
It is another name for an instance variable defined in a class.
3.6.2. Read and write object fields
To access an object field of a class you can use the set method or use the variable name.
obj.name = "Selvan";//as long as access modifier of the variable name is not private obj.setName("Harry");
3.6.3. Calling methods on objects
Java uses the dot notation to execute a method on a reference variable. When calling a method, the exact number of parameters must be passed on it, literal values and variables are also acceptable when invoking a method.
Employee e1 = new Employee(); String anotherVal = "Harry"; e1.setName("Hanna"); e1.setName(anotherVal);
Values returned from a method are also accepted.
e2.setName(e1.getName());
3.7. Apply encapsulation principles to a class
3.7.1. Need for encapsulation
Sometimes when a class is defined, some parts of it must be hidden to other classes to prevent unexpected behavior or security problems.
3.7.2. Apply encapsulation
Encapsulation is the concept of defining variables and methods together in a class. The private members of a class are used to hide the internal information to other classes.
class example { private double num1; }
3.8. Passing objects and primitives to methods
3.8.1. Passing primitives to methods
It is okay to define a method parameter with the same name as an instance variable or object field. Within a method, a method parameter takes precedence over an object field.
class Employee { int age; void modifyVal(int age) { age= age+ 1; System.out.println(age); } }
In the previous example, in order to reference the instance variable age, the keyword this must be used before.
3.8.2. Passing object references to methods
There are two main cases:
- When a method reassigns the object reference passed to it to another variable
- When a method modifies the state of the object reference passed to it
3.8.2.1.Methods reassign the object references passed to them
In the following example, since the object references are passed to other variables, the state of the objects remain intact.
class Person { private String name; Person(String newName) { name = newName; } public String getName() { return name; } public void setName(String val) { name = val; } } class Test { public static void swap(Person p1, Person p2) { Person temp = p1; p1 = p2; p2 = temp; } public static void main(String args[]) { Person person1 = new Person("John"); Person person2 = new Person("Paul"); System.out.println(person1.getName() + ":" + person2.getName()); //prints: John : Paul swap(person1, person2); System.out.println(person1.getName() + ":" + person2.getName()); //prints: John : Paul } }
3.8.2.2. Methods modify the state of the object references passed to them
In the following example, the method modifies the value of both objects person1 and p1:
class Test { public static void resetValueOfMemberVariable(Person p1) { p1.setName("Rodrigue"); } public static void main(String args[]) { Person person1 = new Person("John"); System.out.println(person1.getName()); //prints John resetValueOfMemberVariable(person1); //changes the name System.out.println(person1.getName()); //Prints Rodrigue } }
This entry is the third part of of a series on Java Basics, for further reading:
Java Basics I
Java Basics II
Filed under: Java