Java Programming/Methods
From Wikibooks, the open-content textbooks collection
| Navigate Language Fundamentals topic: |
Contents |
[edit] Method Definition
Method is an operation on a particular object. An object is an instance of a class. When we define a class we define its member variables and its methods. For each method we need to give a name, we need to define its input parameters and we need to define its return type. We also need to set its visibility(private, package, or public). If the method throws an Exception, that needs to be declared as well. The syntax of method definition is:
classMyClass { ...publicReturnType methodName( ParemOneType param1, ParamTwoType param2 )throwsExceptionName { ReturnType retType; ...returnretType; } ... }
We can declare that the method does not return anything using the void java keyword. For example:
privatevoidmethodName(Stringparam1,Stringparam2 ) { ...return; }
When the method returns nothing, the return keyword at the end of the method is optional. The return keyword can be used anywhere in the method, when the executation flow reach the return keyword, the method execution is stopped and the execution flow returns to the caller method.
[edit] Method Overloading
For the same class we can define two methods with the same name. However the parameter types and/or the number of parameters must be different for those two methods. In the java terminology, this is called method overloading. It is useful to use method overloading when we need to do something different based on a parameter type. For example we may have the operation : runAroundThe. We can define two methods with the same name, but different input parameter type:
publicvoidrunAroundThe( Building block ) { ... }publicvoidrunAroundThe( Park park ) { ... }
Related terminology is the method signature. In java the method signature contains method name and the input parameter types. The java compiler takes the signature for each method and makes sure that each method signature is unique for a class. For example the following two method definitions are valid:
publicvoidlogIt(Stringparam, Error err ) { ... }publicvoidlogIt( Error err,Stringparam ) { ... }
Because the type order is different. If both input parameters were type String, that would be a problem again since the compiler would not be able to distinguish between the two:
publicvoidlogIt(Stringparam,Stringerr ) { ... }publicvoidlogIt(Stringerr,Stringparam ) { ... }
The compiler would give and error for the following method definitions as well:
publicvoidlogIt(Stringparam ) { ... }publicStringlogIt(Stringparam ) {StringretType; ...returnretValue; }
Note, the return type is not part of the unique signature. Why not? The reason is that a method can be called without assigning its return value to a variable. This feature came from C and C++. So for the call:
{
logIt( msg );
}
the compiler would not know which method to call.
[edit] Method Overriding
Obviously a method signature has to be unique inside a class. The same method signature can be defined in different classes. If we define a method that exist in the super class then we override the super class method. The terminology for this is method overriding. This is different from method overloading. Method overloading happens with methods with the same name different signature. Method overriding happens with same name, same signature between inherited classes.
The return type can cause the same problem we saw above. When we override a super class method the return type also must be the same. In fact if that is not the same, the compiler will give you an error.
Method overriding is related dynamic linking, or runtime binding. In order for the Method Overriding to work, the method call that is going to be called can not be determined at compilation time. It will be decided at runtime, and will be looked up in a table.
{
1 MyClass obj = new SubOfMyClass();
2
3 MyClass obj = new MyClass();
4
5 obj.myMethod(); // -- During compilation, it is not known what reference the 'obj' has, MyClass or SubOfMyClass
}
In the above example 'obj' reference has the type MyClass on both line 1 and line 3. However the 'obj' reference points two different objects. On line 1 it references SubOfMyClass object, on line 3 it references MyClass object. So on line 5 which method will be called, method define in MyClass, or the method that defined in its subclasses. Because the 'obj' reference can point to object and all its sub object, and that will be known only at runtime, a table needs to be kept with all the possible method address to be called.
Also another rule is that when you do an override, the visibility of the new method that overrides the super class method can not be reduced. The visibility can be increased, however. So if the super class method visibility is public, the override method can not be package, or private.
In the case of the exception the override method may throw can be the same as the super class or it can be one of that exception inherited class. So the common rule is that the override method must throw the same exception or it is any of its subclasses.
NOTE: A common mistake to think that if we can override methods, we could also override member variables. This is not the case, as member variables are not overriden.
{
1 MyClass obj = new SubOfMyClass();
2
3 MyClass obj = new MyClass();
4
5 String var = obj.myMemberVar; // -- The myMemberVar is defined in the MyClass object
}
In the above example, it does not count what object the 'obj' reference points to, because it was declared MyClass type on both line 1 and line 3, the variable in the MyClass object will be referenced. In real examples we rarely use public variables, but if you do keep in mind that Java does not support variable overriding.
[edit] Parameter Passing
We can pass in all the primitive data types or any object references to a method. An object cannot be passed to a method, only its references. All parameters (those are primitive types and object references) are passed by value. In other words if you change the passed in parameter values inside the method, that will have no effect on the original variable that was passed in. When you pass in an object reference to a method and then you change that inside the method, that will have no effect on the original object reference. However if you modify the object itself, that will stay after the method returns. Think about the object reference as a pointer to an object. If you change the object the reference points at, that will be permanent. For example:
1 {
2 int var1 = 10;
3 int var2 = 20;
4 ...
5 myMethod( var1, var2 );
6 ...
7 System.out.println( "var1="+var1 +"var2="+var2 ); // -- The variable values did not change
8 }
9 ...
10 void myMethod( int var1, int var2 )
11 {
12 ...
13 var1 = 0;
14 var2 = 0;
15 ...
16 }
On line 7 the value of var1 is 10 and the value of var2 is 20. When the variables were passed in to the methods their values were copied. This is called passing the paramater by value. In java we do not represent an object directly, we represent an object throught an object reference. You can think of an object reference as a variable having the address of the object. So the object reference passed in by value, but the object itself is not. For example:
1 {
2 MyObjOne obj = new MyObjOne();
3 obj.setName("Christin");
4 ...
5 myMethod( obj );
6 String name = obj.getName(); // --- The name attribute was changed to 'Susan' inside the method
7 }
8 void myMethod( MyObjOne obj )
9 {
10 obj.setName("Susan");
11 ...
12 obj = new MyObjOne();
13 obj.setName("Sonya");
14 ...
15 }
On line 2, we created an object, on line 3 we set its name property to 'Christin'. On line 5 we called the myMethod( obj ). Inside the method, we changed the name to 'Susan' through the passed in object reference. So that change will stay. Note however that after we reassigned the obj reference to a new object, that is no effect whatsoever on the passed in object.
[edit] Return Parameter
A method may or may not return a value. If the method does not return a value we use the void java keyword. Same as the parameter passing, the method can return a primitive type or an object reference. So a method can return only one value. What if you want to return more than one value from a method. You can always pass in an object reference to the method, and let the method modify the object properties. The modified values can be considered as an output value from the method. However better option, and cleaner if you create an Object array inside the method, assign the return values and return the array to the caller. You could have a problem however, if you want to mix primitive data types and object references as the output values from the method. There is a better approach. Defines special return object with the needed return values. Create that object inside the method, assign the values and return the reference to this object. This special object is "bound" to this method and used only for returning values, so do not use a public class. The best way is to use a nested class, see example below:
publicclassMyObject { ... /** Nested object is for return values from 'getPersonInfoById' method */publicstaticclassReturnObj {privateintage;privateStringname;publicvoidsetAge(intval ) {this.age = val; }publicintgetAge() {returnage; }publicvoidsetName(Stringval ) { name = val; }publicStringgetName() {returnname; } } // --- End of nested class defination --- /** Method using the nested class to return values */publicReturnObj getPersonInfoById(intID ) { int age; String name; ... // --- Get the name and age based on the ID from the database --- ... ReturnObj ret = new ReturnObj(); ret.setAge( age ); ret.setName( name );returnret; } }
In the above example the 'getPersonInfoById' method returns an object reference that contains both values the name and age. See below how you may use that object:
{
...
MyObject obj = new MyObject();
MyObject.ReturnObj person = obj.getPersonInfoById( 102 );
System.out.println( "Person Name=" + person.getName() );
System.out.println( "Person Age =" + person.getAge() );
...
}
[edit] Special method, the Constructor
There is a special method for each class that will be executed each time an object is created from that class. That is the Constructor . Constructor does not have a return value and its name is the same as the class name. The Constructor can be overloaded; you can define more than one constructor with different parameters. For example:
publicclassMyClass { private String memberVar; /** * MyClass Constructor, there is no input parameter */publicMyClass() { ... } /** * MyClass Constructor, there is one input parameter */publicMyClass( String param1 ) { memberVar = param1; ... } }
In the above example we defined two constructors, one with no input parameter, and one with one input parameter. You may ask which constructor will be called. Its depends how the object is created with the new keyword. See below:
{
...
MyClass obj1 = new MyClass(); // The constructor with no input parameter will be called
MyClass obj2 = new MyClass("Init Value"); // The constructor with one input param. will be called
...
}
In the above example we created two objects from the same class, or we can also say that obj1 and obj2 both have the same type. The difference between the two is that in the first one the memberVar field is not initialized, in the second one that is initialized to 'Init Value'. obj1, and obj2 contains the reference to the object. Each class must have a constructor. If we do not define one, the compiler will create a default so called empty constructor automatically.
publicclassMyClass { /** * MyClass Empty Constructor */publicMyClass() { } }
The Constructor is called automatically when an object is created with the new keyword. A constructor may also be called from an other constructor, see below:
publicclassMyClass { private String memberVar; /** * MyClass Constructor, there is no input parameter */publicMyClass() { MyClass("Default Value"); } /** * MyClass Constructor, there is one input parameter */publicMyClass( String param1 ) { memberVar = param1; ... } }
In the above example, the constructor with no input parameter calls the other constructor with the default initial value. This gives an option to the user, to create the object with the default value or create the object with a specified value.
[edit] Static Method
We defined method above as an operation on an object. Static Methods are defined inside a class, but they are not an operation on an object. No object needs to be created to execute a Static Method, they are simply global functions, with input parameters and a return value.
publicclassMyObject {staticpublicStringmyStaticMethod() { ... return("I am a Static Method"); } }
Static Methods can be referenced anywhere prefixed by the class name. See below:
{
...
// --- Call myStaticMethod ---
System.out.println( "Output from the myStaticMethod:" + MyObject.myStaticMethod() );
...
}
You can write a non object oriented program by using only Static Methods in java. Because java evolved from the C programming language, Static Method is a left over from a non object oriented language.
You write Static Method the same way as normal method, the only difference is that you can not reference any member variables and any object methods. Static Methods can reference only Static variables and call only other Static Methods. However you can create an object an use it inside a Static Method.
publicclassMyObject {publicStringmemberVar;staticprivateStringmemberStaticVar;staticpublicStringmyStaticMethod() { memberVar = "Value"; --> ERROR Cannot reference member var. memberStaticVar = "Value"; // --- This is okay, static vars. can be used // --- Create an object --- MyObject obj = new MyObject(); obj.memberVar = "Value"; // --- This is okay since an object is created -- ... return("I am a Static Method"); } }