Procedural abstraction
- Procedural abstraction means hiding how a value is computed or how an effect is achieved.
- Procedural abstraction allow us to “decompose” or break down a large problem into smaller sub-problems by writing procedures that call other procedures that each solve various sub-problems.
Methods
- In Java the unit of procedural abstraction is the method.
- We can use methods provided to us by Java (as in the
Math
methods such as Math.sqrt
) and also methods that we write ourselves.
- We can use methods without knowing exactly how they are implemented but it is also useful to write our own method to hide details in one part of our code even though we have to deal with those details when we write the method.
- The code in one method can call other methods, allowing us to build layers of abstractions.
- A method can also call itself. This is called recursion and we’ll talk about it separately in a later unit.
Method structure
- Method signatures must specify three things: the return type, the name of the method, and the method’s parameters.
- The return type specifies the kind of value the method returns. The special return type
void
indicates that a method does not return any value. All non-void
methods must return a value of the specified type.
- Methods with
void
as their return type are called “void
methods” and are called only for the effects they have, such as printing to the screen or changing the state of an object.
- Method parameters are variables and thus must be specified with a type and a name. The scope of method parameters is the body of the method. Outside of a method the names of the method’s parameters have no meaning.
- Because method parameters are purely local to the method, different methods can have parameters with the same names without any problem.
- Methods that take no arguments are written with an empty parameter list consisting of just a pair of parentheses.
- The body of the method follows the signature and is enclosed in a pair of
{}
s.
- Within the body of a method we can declare other local variables whenever we need them. Like parameters, the scope of these variables is limited to the body of the method and the names have no meaning outside of the method.
- Code within the body of a method can refer to the parameters declared in the method signature as well as any local variables declared in the method and any
static
variables declared in the class. Code in instance methods can also refer to any instance variables defined in the class and the special variable this
which refers to the object on which the method was invoked.
Method calls
- Method calls consist of a reference to the method and a possibly empty argument list consisting of a comma-separated list of expressions, e.g.
foo(10, "some string")
.
- The expressions in the argument list are evaluated to get the values that are passed as the arguments to the method. When the method runs the parameters declared in the method signature are initialized to the values of the corresponding arguments, with the first parameter getting the value of the first argument, and so on.
- The arguments passed to a method must be compatible with the types identified in the parameter list.
- Arguments are passed to methods by copying values. This means that there is no way for code in a method to change the value of local variable in the method that called it.
- Recall, however, that the value of a reference type is the reference itself; this means code in a method or constructor that is passed a reference to a mutable object can use the reference to alter the state of the object and those changes will be visible to other code that also has a reference to that object.
- As a matter of good coding practice, methods should not modify mutable objects passed as arguments unless doing so is an inherent part of the method’s purpose.
- Calling a method causes the flow of control to jump to the start of the method after initializing the parameters. When the method returns, the flow of control returns to the point where the method was called. No code executes in a method after a
return
statement.\note{Technically, that’s not quite true; there are constructs that are not covered in the AP curriculum that allow us to guarantee that certain bits of code execute just before returning from a method.}
- The parameters of a method and other local variables declared in the method exist only until the method returns.
- Values are returned from a method using a
return
statement consisting of the keyword return
followed by an expression that evaluates to a value of the correct type which is then returned from the method. (In a void
method return
is only used with no following expression to return early from a method.\note{It is legal but unusual to use an empty return
statement in a constructor. It can be used to exit from a constructor early but constructors do not return a value; they merely initialize the object that will be the value of the new expression that invoked the constructor.})
- The value returned by a method is copied, just like method arguments. Again, this means a reference returned by a method can be used to modify object it references.
- A method call to a non-
void
method is a kind of expression whose value is the value returned by the method.
- A call to a
void
method can only be for effect and not part of an expression since the method doesn’t return any value. They typically do not need a return
statement and simply return when execution reaches the end of the method.
Naming methods in method calls
- Within a class, code can reference other methods in the same class simply by their name with the exception that
static
methods cannot call instance methods without an explicit object to invoke the method on. But in non-static
methods, invoking a method by its simple name is the same as invoking it on this
, i.e. on the same object the current method was invoked on.
- Outside a class,
static
methods are typically referenced using the class name, the dot operator, and the name of the method, e.g. Math.sqrt(2)
to invoke the static
sqrt
method in the class Math
.
- Instance methods in other classes are invoked on a particular object using an expression that evaluates to a reference to the object, the dot operator, and the name of the method, e.g.
s.substring(1)
to invoke the substring
method on an instance of String
referenced by the variable s
.