java chap4: functions defining methods(prof. ananda m ghosh.)

23
Chapter 4: Functions Defining Methods 4.0 Introduction Objects created from a class are capable of behaving according to the methods lying defined within that class. The question is – how to write codes for those methods? Methods are written in the form of functions. That is why, methods are also called functions. Then the next question comes -- what is a functional form? Those who are familiar with algebraic functions already know the answer. If we say --- y is a function of x or y = f(x) – then you understand that if a value of x is passed to the function f(x), a y-value will be returned. For example – say, y = 3x + 5; if we pass a value of x as 2, the function will return a value of 11. A function can be taken as a block capable of accepting zero, one or more input parameters but returning a single output as shown in fig-4.1 (a). Output y x Input(s) Fig-4.1(a) A Functional block So a function, to its users, can be regarded as a black box which is capable of returning an output value [obtained according to the codes written inside] when its users feed some input argument(s). All methods in a java class take this view of a functional form as shown in fig-4.1 (b). Therefore, java’s methods are nothing but functions. f(x

Upload: ananda-mohan-ghosh

Post on 10-Apr-2015

2.607 views

Category:

Documents


4 download

DESCRIPTION

How to define methods of a Java Class

TRANSCRIPT

Page 1: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

Chapter 4:

Functions Defining Methods

4.0 Introduction

Objects created from a class are capable of behaving according to the methods lying defined within that class. The question is – how to write codes for those methods?

Methods are written in the form of functions. That is why, methods are also called functions. Then the next question comes -- what is a functional form? Those who are familiar with algebraic functions already know the answer.

If we say --- y is a function of x or y = f(x) – then you understand that if a value of x is passed to the function f(x), a y-value will be returned. For example – say, y = 3x + 5; if we pass a value of x as 2, the function will return a value of 11.

A function can be taken as a block capable of accepting zero, one or more input parameters but returning a single output as shown in fig-4.1 (a).

Output y

x Input(s) Fig-4.1(a) A Functional block

So a function, to its users, can be regarded as a black box which is capable of returning an output value [obtained according to the codes written inside] when its users feed some input argument(s). All methods in a java class take this view of a functional form as shown in fig-4.1 (b). Therefore, java’s methods are nothing but functions.

Input argument(s), if any output of the < return type>

Fig-4.1 (b) Java’s Method block

Next question – what are the advantages of having this functional form of a class-method? The answer is –i) to hide low-level inner code details from its users. External use of methods may be

allowed without exposing inner details; ii) to reuse portion(s) of class codes, as and when necessary, by simply using the

method-name, and

f(x)

Java codes inside a method

Page 2: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

iii) to divide a complex computational task into a collection of smaller methods so that problem solving becomes easier, object-specific and modular.

All these aspects will be clear gradually as we go further into its details.

The general form of a member function of a class is shown below:

[access-specifier] <return-type> function-name ( parameter-list){ body of the function; return < output>; // if Computational type}

where

[access-specifier] can be either public or protected or private type.

When a function is specified as private, a member of that class type only can use that function. Any member, even belonging to external classes can use a public function or method. Protected is mainly concerned with the inherited class types. That is, only inherited class members can access the protected functions.

When no access –specifier is mentioned, by default java takes that function as public within its own package boundary. [A folder or directory containing a number of defined classes forms a Package]. Detailed discussions about such packages will be made in chapter-9.

<return-type> is concerned with the data type ( like int, double, char, boolean, etc. ....) of the output produced by the function. It may so happen that a function is defined to take some actions inside but not to return any output value. Even in that case, the return-type should be marked as void.

When a function is defined to return some output, the body of the function must include the statement -- return < output variable>;

Each function, except those of type void, actually returns a value of the specified data type. That is the property of a function. A function can be classified according to its internal activities.

A Computational Function has to return some output value.A Manipulative Function can return success or failure information by outputting 0

or 1 respectively. A Procedural Function, which takes some inner actions (like input/output

operations) but does not return any output value, but defined with the return-type as void.

Page 3: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

(parameter list) – a list of comma separated input variables, with their respective data types, required by the function for internal computation. An empty parameter list for a function is very much allowed. For example ---

In addMethod() function – access-specifier is public and the return-type is double, because it returns the sum of x and y values which were declared individually as double [ see example-2.1]. Moreover, that function needs no input argument to pass, that is why the parameter list is empty.

public double addMethod( ) { return x + y;

}

In cosMethod() function – access-specifier is public but return-type is void, because the function does not return any value. This function makes use of a public library function sin(rad) which is a member of the Math class and it accepts only one parameter – i.e. angle expressed in radian [ example-2.12].

public void cosMethod(){double rad = deg*22/(7*180); double result = Math.cos(rad); // using Math class of java.lang package System.out.println(" cos of the angle =" + result);}

However, parameter list of a function can take the general form of –

<function-name> ( type variable1, type variable2, ... , type variableM) { function body; }

Please note that always meaningful function-name should be chosen. Function-name normally starts with a lowercase letter. You will notice that a function-name tries to use a verb because every method is supposed to take some action(s) inside or output some data-value doing computation within the functional block.

4.1 Pure Functions

Functions are mostly used to produce some computational output. Actions inside a function may be like reading and displaying some data values; assigning or modifying some existing values; computing and returning a result for further use, etc.

Page 4: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

Out of all such actions, some operations like write or modify can disturb or change the value of some already stored member-data. Therefore, write or update operations are to be treated very carefully and unrestricted public access should not be allowed. On the other hand, read or display operations are not destructive, because read operations do not change data values. So no access restriction will be necessary for such operations.

Based on the operational side effects, functions can be classified as either pure functions or impure functions.

A pure function, when invoked, does not cause any change in the state of an object, that means there will be no change in the values of the object’s instance variables.

For example readData() or getData() functions can be treated as pure functions as they do not change any existing data values.

Pure functions can safely be declared as public also.

Now the use of a pure function will be demonstrated [see example-4.1].

// Example-4.1 Demonstration of a Pure Function

public class PureFunc { // instance variables String name; int rollno; int total; char grade; public char gradDiv( int tmarks) { if (tmarks >= 750) grade = '*'; else {if( (tmarks >= 600) & (tmarks < 750)) grade = 'F'; else if ((tmarks >= 400) & (tmarks < 600)) grade = 'S'; else if ( tmarks <400) grade = 'P';} return grade; } public void display( int roln, char grad) { System.out.println(" Roll No. : " + roln + " Division: " + grad); } public static void main() { PureFunc std1 = new PureFunc(); //first object created std1.name = " Ashoke"; std1.rollno = 3216;

Page 5: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

std1.total = 583; std1.grade = std1.gradDiv(std1.total); System.out.println ( "Student Name :" + std1.name); std1.display( std1.rollno, std1.grade); PureFunc std2 =new PureFunc(); //second object created std2.name =" Bimala"; std2.rollno = 5432; std2.total = 808; std2.grade = std2.gradDiv(std2.total); System.out.println(" Student Name : " + std2.name); std2.display( std2.rollno, std2.grade); } }

If you run this program, you will get the output as shown below –

Student Name: AshokeRoll No: 3216 Division : S

Student Name : BimalaRoll No : 5432 Division : *

Please Note:

1) The states of the objects std1 and std2 remain unchanged in whatever way you run the pure method display (int, char). There will be no change in the object’s state.

2) Carefully observe how the control if-else statements are used in the gradDiv(int) method. Details about such control statements you will learn in chapter-6.

3) The class PureFunc has used three methods – gradDiv(int), display(int,char) and the main() method.

4.2 Impure Functions

Impure functions, also called modifier functions, are those that can cause a change of state in the object. That means, values of the object’s instance variables get modified or changed depending on the current state of the object on which the function operates. Such functions can cause some unwanted side effects if not carefully controlled by the access-modifier.

So more restrictions are to be imposed on the use of such impure functions. To impose different categories of restrictions – java allows optional inclusion of modifier along with the access-specifier while defining member functions or methods of a class.

Page 6: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

A modifier can be one of – final, native, synchronized, transient, volatile. The functionality of a final method can never be changed. Final modifier prevents overloading [not allowing same function names with different arguments] of functions. Final modifier also prevents inheritance that is creation of a sub-class from a pre-defined base class is not allowed. For advanced java programmers, knowledge of other types of modifiers may be necessary but for the beginners, those are unnecessary and have been kept out of scope of this book.

// Example-4.2 Demonstration of an Impure Function

public class ImpureFncTest{

// instance variables String name; int accNo; double accBalance; double withdrawVal; public double transaction(double balance, double withdraw) { if ( withdraw > balance) { System.out.println("Sorry !! Transaction Impossible."); } else { balance = balance - withdraw; System.out.println("Transaction Successful."); } return balance; } public void show( double bal){ System.out.println ( "Balance Available : " + bal); } public static void main() { // manipulation of the first object ImpureFncTest customer1 = new ImpureFncTest(); //first object customer1.name = " Anita Kar"; customer1.accNo = 8912; customer1.accBalance = 123456.50; customer1.withdrawVal = 5000.00; System.out.println ( customer1.name + " -- Account No. :: " + customer1.accNo);

customer1.accBalance = customer1.transaction(customer1.accBalance, customer1.withdrawVal);

customer1.show(customer1.accBalance); // manipulation of the second object

Page 7: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

ImpureFncTest customer9 = new ImpureFncTest(); //second object customer9.name = " Kalyan Bhatt"; customer9.accNo = 13245; customer9.accBalance = 3592.75; customer9.withdrawVal = 4000.00; System.out.println ( customer9.name + " -- Account No. :: " + customer9.accNo); customer9.accBalance = customer9.transaction(customer9.accBalance,

customer9.withdrawVal); customer9.show(customer9.accBalance); } }

If you run this program, you will see the output as shown below (picture 4.1)–

Picture 4.1

In this example, transaction (double, double) is an impure function, because it causes a change in the object’s state by changing the value of the Balance Available.

Also note that the function main () can include both the types of member functions – pure or impure. Programmer must be very careful about defining impure functions so far as access-specifier is concerned.

4.3 Arguments to Functions

As mentioned earlier, functions are capable of accepting zero (i.e. no argument), one or more argument variables to return either one or no output value. Input values are passed as arguments to the formal parameters while calling a function or method. For example: -

Example-4.3 Computation of Area by passing Two Arguments// length and width data -- are passed to function cover

public class Area{ int length, width;

Page 8: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

public int cover(int l, int w){

length =l; width =w; return (length*width);

}}

// utilizing the function cover ( ) of the class Areapublic class AreaDemo{

public static void main(String args[]){ // two objects created out of class Area Area area1 = new Area(); Area area2 = new Area(); System.out.println(" Covered area of 1 = " + area1.cover(15,10)); System.out.println(" Covered area of 2 + " + area2.cover(25,15));

} }

Picture 4.2 Outputs of example – 4.3

Please note that the function cover of the class Area is defined to accept two argument values — length and width. In AreaDemo class, the default Area () constructor is utilized to create two area objects – area1 and area2, which can use the cover function by passing appropriate argument values i.e. (15,10) and (25,15) respectively as shown in example-4.3.

4.4 Function Prototype & Function Signature

A function prototype is the first line of a function definition which describes the return type of the output and the number and type of arguments to be passed to call it along with its name and access-specifier. In example-4.3 the prototype of the function cover () is

public int cover(int l, int w)

Page 9: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

Compiler checks each use of a function prototype during every invocation of it and report error(s) in case of any mismatch.

On the other hand, a function signature is concerned mainly with the numbers and data types of the arguments to be passed during its invocation by calling function name. The signature of function cover () of example-4.3 is simply cover (int, int). Therefore, a function signature is concerned with the function-name and arguments only, whereas a function prototype takes care of the full functional interface -- including the signature, return type of the output, access-specifier, modifier, etc.

4.5 Function Overloading

Like constructor overloading, a function overloading is very much allowed in java. That means, in a java class more than one method can have the same name but they must have separate signatures --- i. e. arguments with different data types and with different numbers of them. Thus function overloading is made possible due to different function signatures. An example here can make the conception clear.

// Example-4. 4 Function OverLoading

public class OverLoad{

int a; double r;

public void show(){

System.out.println(" Nothing to show.");}public void show(int x)

{ a = x; System.out.println(" The value of a is =" + a); } public void show(int x, int y) { a = x*y; System.out.println(" The value of x*y is = " + a); } public void show(double u, double v) { r = u+v; System.out.println(" Sum of two numbers is = " + r); }

}

Page 10: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

// The DemoOL with the main () method

public class DemoOL{

public static void main(){ OverLoad obj = new OverLoad(); obj.show(); obj.show(25); obj.show(12,36); obj.show(7.6,13.4); }

}

This program, on execution will produce the following outputs:

Nothing to show.The value of a is = 25The value of x * y is = 432Sum of two numbers is = 21.0

In this example-4.4, the method show () is overloaded four times. The first one takes no argument and displays “Nothing to show”. The second one takes one integer parameter and displays that value. The third one accepts two integer parameters and displays the product of those two. Finally the fourth one takes two double type parameters and displays the sum of them. Four overloaded methods are performing different tasks although they bear the same function name.

Function overloading is an example of polymorphism by which one functional interface can take care of multiple methods. The overloaded functions are all having a common name but multiple argument signatures, that is different types or number of arguments. This overloading mechanism helps accommodating different arguments for different situations to tackle. The programming flexibility is thus enhanced.

4.6 Object Variable as a Reference to the Class type

Whenever you define a class, a new special data type gets created for use in your program. Different Objects of that user-defined data type can then be created and used.

Creating objects out of a class is a two-step process. One, to declare a variable of a particular class type and two, acquiring a physical copy of that class type and connecting that memory chunk with a reference address. The new operator allocates memory for the object and returns a reference to it. This reference is then stored against that object of the class type variable. In example-4.4, by the expression

OverLoad obj = new OverLoad();

Page 11: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

the object obj gets created with a reference to the starting address where it is supposed to appear physically.

Class type variable

reference obj

Fig - 4. 2 Class type Variable obj refers to the memory space

In reality, the variable obj simply holds the memory address where the actual OverLoad object exists. That object has links to four reference addresses for four over loaded functions named show (...). During run-time those addresses are resolved by observing the arguments passed along with the function call (example-4.4).

4.7 Invocation of Functions on the Created Objects

Any object created out of a class type can invoke any method(s) or function(s) belonging to that class. So the object obj of OverLoad class type can invoke any one of the show (..) functions as per argument matching. Four overloaded function – show (...) -- have been called (example-4.4), simply by passing appropriate arguments.

obj.show(); // no argument obj.show(25); // with one int type argument obj.show(12,36); // with two int type arguments obj.show(7.6,13.4); // with two double type arguments

Therefore, we can say that the function invocation or call has a general form of –

<object-name>.function-name( nil or argument[s] of proper data type[s]) .

While defining a function formal parameters are specified, but during invocation of that function, argument values are to be passed.

Just take a note of the use of (.) dot-operator in-between the object-name and the function-name.

4.8 Concept of this

Sometimes a function needs to refer to a particular object, which is allowed to invoke it. The this keyword can be used for that purpose. This refers to an object currently being used.

An object of the OverLoad class type createdIn Memory

Page 12: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

This can also be used as a reference to an object’s instance variable that can have different reference for different object being created out of the same class type.

// Example-4.5 An Example of the use of this

class ThisDemo {

// instance variables int age; double fare; public void setAge(int yrs) { if (yrs <5) { this.fare = 0.0; } else { this.fare = 125.0; } } public void issue( int ag, double price) {

System.out.println ("Age " + ag + " years"); System.out.println ("Fare to pay :" + price); } } public class PassTicket{

public static void main(){ ThisDemo passenger = new ThisDemo(); // passenger object created passenger.age = 25; passenger.setAge(passenger.age); System.out.println (" Issue Ticket"); passenger.issue (passenger.age, passenger.fare); ThisDemo child = new ThisDemo(); // child object created child.age =3; child.setAge(child.age); System.out.println (" Ticket Unnecessary!!"); child.issue (child.age, child.fare); } }

Page 13: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

Picture 4.3 Outputs of example-4.5

In example-4.5, this has been used to refer to the currently active object – either passenger or child. The use of this keyword becomes essential when instance variables of multiple categories of objects try to access the same method or function.

The keyword this can be used to hide local variables inside a method having the same name as that of the class’s instance variables. In fact, this refers directly to the object. So it can be used to resolve any name space conflict that might occur between instance variables and local variables.

In example-4.5, the class methods are coded with this keyword, but the main () method invokes them with the objects’ instance variables. This just returns reference to the currently used object. Here, this refers first to the passenger object and then to the child object according to the reference of the object being used.

A word of caution: Programmers must be careful in using local variables and formal parameter names so that no hidings of instance variables can occur.

4.9 Argument Passing in Functions

There are two ways of passing an argument to a function – call-by-value and call-by-reference. In the first case, the value of an argument is directly copied into slot of the formal parameter. So there will be no side effects due to such parameter passing.

On the other hand, in call-by-reference, a reference (i.e. address) to an argument is passed to the parameter slot. This reference is then used to access the actual argument specified. Java allows both the methods of argument passing.

4.9.1 Call-by-Value

When a simple primitive type data (like int, double, float, boolean, char, etc) is passed to a method or function, call-by-value is used. The actual benefit of call-by-value is that call does not put the value in the location where the original function resides, but the value

Page 14: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

change occurs only inside a copy of that function. Thus original definition with any argument values remain unaffected.

// Example-4.6 Use of call-by-Value

public class Test { void method(int i, int j) { i = i * 5; System.out.println ("Value of i within test method:" + i); j = j / 3; System.out.println ("Value of j within test method:" + j); }

}

public class CallByVal { public static void main() { int x = 4; int y = 21; System.out.println("Values of x & y before Call :: " + x + " " + y); Test obj1 = new Test(); obj1.method(x,y); // calling method with values x=4 and y=21 System.out.println(" Values of x & y after Call :: " + x + " " + y); } }

If you run this program, the following output will appear in the Terminal Window –

Values of x & y before Call:: 4 21Value of i within test method: 20Value of j within test method : 7Values of x & y after Call:: 4 21

This shows that call-by-value does not cause any change in the values of x and y used in the call.

4.9.2 Call-by-Reference

Any object can be passed to a method or function using call-by-reference. Since reference points to the address of an object including its methods inside, any change in the methods internal value will cause a change in the state of that object. So call-by-reference will give rise to side effects.

// Example-4.7 Use of Call-By-Reference

class TestRef { int a,b;

Page 15: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

TestRef (int i, int j) { a = i; b = j; } void method( TestRef objRef) { objRef.a *= 3; objRef.b += 10; } }

public class CallByRef { public static void main() { TestRef obj2 = new TestRef(10, 25); System.out.println (" Values of obj2.a & obj2.b before Call:: " + obj2.a + " " + obj2.b); obj2.method ( obj2); System.out.println (" Values of obj2.a & obj2.b after Call:: " + obj2.a + " " + obj2.b); }

}

If you run this program, the Terminal window will show the following (picture 4.4) –

Picture 4.4 Outputs of example-4.7

4.9.3 Side Effects of Call-by-Reference

You have just observed that passing argument using call-by-reference gives rise to a change in the parameter reference. Within the parameter slot -- a reference address pointing to data is put and not the actual data value. This can cause the side effects.

If the data value in the pointed location gets changed, the value accessed by the reference pointer reads the changed value, not the value stored earlier. Whenever any argument is passed to an object, side effects are bound to occur because objects are bound by references. Java programmers should always remain careful about such side effects.

Page 16: Java Chap4: Functions Defining Methods(Prof. Ananda M Ghosh.)

4.10 Conclusions

In a function oriented language, like C, both data and functions have isolated existence within a program. But in Java, functions or methods remain enclosed together with data members within a class or object and only those functions are capable of manipulating any inside data member. This feature hides the internal details of an object but allows external class/objects to interact through function interface by passing messages. These interfacable functions of a class can be of either pure type or impure type.

A pure function does not cause any change in the state of an object, which means that the called function does not cause a change in the values of instance variables. So pure functions can be safely declared as public.

An impure function causes a change in the state of an object; so proper protection mechanism using appropriate access specifier should be used.

The difference between function prototype and function signature has been explained with examples.

The importance of this keyword is also demonstrated. The concept of function overloading has been thoroughly explained and illustrated.

Argument passing is another very important aspect of any function call. Argument(s) can be passed using either call-by-value or call-by-reference technique.

Call-by-value has no side effect; but call-by-reference gives rise to side effects. A programmer must keep this point in mind. Call-by-value can be used with simple primitive data types, but call-by-reference is got to be used for complex data types like object(s).