| Chapter 6: A Closer Look at Methods and Classes (pp. 201-250) |
Session 6Access specifiers
Passing objects to methods
Returning objects from methods Overloading static keyword |
| The cell wall encapsulations all the members that are private to the cell. | A medicine capsule encapsulates its ingredients or components. |
![]() |
![]() |
A Java class encapsulates its members (constructor, fields, and methods).

Normally, the engine is encapsulated under the hood, and access is not public.

In 1955, when no one was worried about someone siphoning away gasoline from their Chevrolet, the gas cap did not have to be locked, but it still was encapsulated behind the tail light.

When gasoline became scarce in 1973, gas tank access became private.

This example demonstrates the protective action of the keyword
private.
A private member can only be access from within the class in which it is
declared.





First, let's consider what a stack is, then let's look at how to use access control with a stack.
The stack is the part of memory that provides speed, and primitives are
loaded onto the stack, which is like a one-dimensional pile of plates to be
washed: last-in, first out (LIFO).

The protocol for dishwashing does not require much memory.
The heap is the part of memory that affords capacity for custom types.
Objects exist in the heap.
Working with the heap requires more memory and is slower, but more the
possibilities are more versatile.
You can think of it as like a spreadsheet with a column for each field, and row
for each object.
When we create an object with the new
operator, the Java virtual machine allocates memory for that object on the heap.
(Class members that are static are separate from the heap
in a centralized location for availability to all instances.)

The Data class might provide a public method to get the current date, but not allow programmers of other class to reset the values of the date.

A Date object inherits private fields for day, month, and year. Two different programs might have a variables, such as d1 and d2, the both refer to the current date.

The class with main does not know about the internals of the Stack class. Instead, the class is a sort of black box that is encapsuled, although it provides a sort of interface: the push and pop methods. The person writing the application with main cannot alter the stack, and the developer of the code within the Stack methods can optimize the methods (or fix its bugs) without breaking the application that uses them. The value in the stack and the array container that holds the stack value are both private. The keyword private restricts access to the class that declares the member. The calling class can see is the value that the pop method returns but has no access to the production and storage of the value.


Just pushed onto initial stck T
Just pushed onto initial stck o
Just pushed onto initial stck m
Put an array of chars onto stk2 as name: T o m
pushed onto stk1 J
Contents of stk1 will be popped from the end toward the front: JIHGFEDCBA
Contents of stk2 will be T o m backward: moT
Contents of stk3: JIHGFEDCBA
The Java virtual machine has its own stack, as does the underlying operating system. However, sometimes the application program needs to implement a stack for the application. This is a general feature of the language, so it is in the java.lang package.
The following program uses the Stack class, which is part of the java.lang package.
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Stack.html
(The following is from http://www.ccs.neu.edu/home/jshan/com3113/schildt-sources/)


The output is:
Stack in mystack1: 9 8 7 6 5 4 3 2 1 0 Stack in mystack2: 19 18 17 16 15 14 13 12 11 10
TestStack does not have access to the
private array called stck in the Stack class.
Does TestStack have access to the tos
property?
What visibility do the push and
pop methods have?
Another example of using the private keyword is closer to a business use case: Human Resources needs to access an employee's ID, but cannot alter the employee's record.

The sameBlock method takes an object.

The output is:
ob1 same dimensions as ob2: true
ob1 same dimensions as ob3: false
ob1 same volume as ob3: true
A constructor can also take an object parameter, such as a String, as well as a primitive parameter.

Calling by value is for primitives. Calling by reference is for objects.

Even though line 22 calls the meth() method, the result of lines 23-24 show that these lines see the same values as those declared in line 16.
However, an object is a special type that has, if you will, a history or a "state" of existence, which is something that a primitive type does not have.

Calling the constructor in line 25 passes in values that get assigned to a
and b in lines 8-9.
However, in this example, a and b are
not just integers: they are fields on an object.
Therefore, the logic of lines 16-17 operates on data belonging to an object of
type Test
(ob is an instance of the class Test
) which is called
o.
Line 30 passes an object as a parameter to the meth
method.
Line 25 calls the Test constructor with initializing parameters that get
assigned to the member variables a
and b.
An object is an instance of a custom data type. We saw that a method can take an object as a parameter (previous example, line 30). Similarly, an object can also be the return value of a method. Note the use of the keyword return in line 16, which fulfills the contract the method returns an object of type Test.

Overloading is when a method (or constructor) has more than one signature. Overloading is useful to have slightly different behavior for different situations, and yet reduce the number of names. Imagine if a bank had to have all of the following method names:
A signature is a pattern for the arguments and formal parameters:
The concept of overloading exists in natural speech.
Overloading a method or a constructor is less complicated that having to have a separate name for each combination of method name and method signature.
Overloading is the primary way in which Java allows you to implement the object-oriented concept of polymorphism: many forms for the same thing. For example, you might want your bank to allow you to open an account even if you do not deposit money, or to open an account that initially has associated with it not money but a credit card number. openAccount(217.34) versus openAccount() versus openAccount(visaCard555555555)
So we have three constructors, one with double, one with no arg, and one with int. That easier than having openAccountWithDouble, openAccountNoArg, openAccountWithInt.
Let's look at this demonstration:

Sometimes it is convenient to have one name for something even it takes several slightly different forms.
The English words "drive" and "ride" are polymorphic, because there is a different form of driving or riding, depending on the class of the vehicle.
If the only difference is that between one car and another car, the drive method remains the same (except driving a manual transmission has an additional parameter than driving an automatic transmission does not).
Certainly, when driving different cars, such as a sedan and an SUV, we have a difference in properties (data), but not in behavior.
Polymorphism has to do with behavior (methods).
We "greet" different people with different levels of formality. We behave in
different forms, using multiple form, or many forms: poly-morphic.
It makes our language more simple when we can use the same word for closely
related forms.
The same word means different things in different contexts.
Otherwise, we would need to have many more words, and that would be
inconvenient.

Java has its counterpart to this flexibility of natural language.
The compiler looks for the "signature" of a method. Multiple methods can have
the same method name, and yet have different signatures.
For example:
We say that myMethod() is overloaded, and has six signatures.
The following does not compile because the method signatures are not unique.
For this purpose, it does not matter what the return type is, nor what name
is assigned to the formal parameters.
A signature consists of the:
Therefore, a method with one argument can have multiple signatures with one argument if that argument has a different data type for each signature.
Indeed, we can say that a given method can have multiple forms. Overloading
is an example of polymorphism.
Because a single class can have one or more overloaded methods, overloading
helps make it practical to have encapsulation by class.
Every instance of a class--that is, every object--inherits all the
properties and methods of that class, including any overloaded methods.
Note: Java classes are only polymorphic insofar as the methods of those classes
are polymorphic. Polymorphism is a
concept relate to behavior (methods).
Let's see some overloaded methods:
Here's an example in which the method definition requires an object as a parameter (line 13). Therefore, the method calls in lines 30-32 have runtime arguments that were instantiated in lines 25-27.

The flexibility for objects of the same class having different properties (data) often appears as a series of overloaded constructors. A class can have 0, 1, or many custom constructors.
The following example of constructor
overloading has two constructors that take a single argument.
Which are the lines the code that call these two constructors, and how does the
javac
compiler know the difference between the two constructors?

In Week 4 (p. 139) we learned about the default constructor. If you do not define any constructor(s) for a class, Java automatically
provides a default constructor that has no arguments.
However, if you define any constructor(s) for a class, then you must define them
all, and Java provides no default constructor.

In this example, we use a custom constructor that has the same signature as the default constructor, that is, no parameter (lines10-15). However, this custom constructor does custom initialization because it assigns hard-coded values to box objects.

Going a step further, here the constructor definition (lines 10-14) defines a
signature that allows us to pass in actual values when we call the constructor
to make objects (lines 26-27).
The constructor has a signature that facilitates making each box object
different. Instead of using the default constructor, this class has a
parameterized constructor.

It is common for a class to have multiple constructors.


The output is similar to the following, but the random number generator forces different ID numbers for each run:
name=Harry,id=2125,salary=40000.0 name=Employee #2126,id=2126,salary=60000.0 name=Mary,id=2127,salary=80000.9 name=,id=2128,salary=0.0 name=Employee #2129,id=2129,salary=68888.0
In this example, the initial constructor does the minimum initialization. The subsequent constructor added additional initialization. This avoids writing the logic of lines 9 and 10 two times. However, each constructor call does incur the delay of object creation.
A recursive method is
a method that calls itself.
For example, a method that calls itself upon the previous result of calling
itself.
Factorial:
5! = 5 * 4 * 3 * 2 * 1
Note that factorial 0 = 1 by definition.

Which method calls which method in line 7?
Notes:
Question: Why is it possible for a recursive method to cause the stack to overrun?
The modifier keywords include
http://java.sun.com/docs/books/tutorial/reflect/class/getModifiers.html
The HelloWorld.java program is the first
place we saw the keyword static.
The main() method must be static because
the Java Virtual Machine needs to call the main()
method BEFORE any objects exist. If you forget to make main static, the runtime
cannot main because it would expect any method to require being on an object,
which would mean calling a constructor to get an object BEFORE calling a method
on that object.
If a class has a static member (variable or method), then that method is
independent of an object.
Static members exist before the coming and going of objects. They are in a
different place in memory than the instance variables.
Static members are efficient for memory: there is only one copy, no matter how
many objects exist, Java stores static values in a separate place.
In the sense of
their always being there, they are outstanding or pre-standing or standing by (standing in Latin is
static).
main must be static so that execution can begin. Note that we never call main, we only define main. Normally, a method is only available on an object, and we would first have to create an object. We would have to say HelloWorld hw = new HelloWorld(); but that still leave us the problem of which method would contain the call to the constructor. (Static is Latin for "standing, having status". A static member has a special status: it stands already ready, independent of the initialization of an object.)
This is analogous to the paradox of "Which came first, the chicken or the egg". The answer is that static came first. You can begin with either a static egg or a static chicken, or make both static. Static means something does not need to have a beginning. Static means something is always already there at the beginning.
![]() |
A French anthropologist found a "native" tribe that did not have radio or television. There were not impressed with Coke commercials. They considered any program with people talking or people moving to be unreal. "Those are not people." What they did consider real, is static. "We recognize the full pulse and rhythm of the natural world." |
The tribe understood that static pre-exists the specific orders of the main method.
It is as if there were a static method, makeRandomNoise() from which the accidents begin that provide the random mutations that make possible the occasional adaptations that drive nature, and can be observed over long periods of time as evolution. As if the uncertainty principle (instead of intelligent design) is the creator.
But on the other hand, you can view static as the opposite of noise: it is in static main that you deliberately drive your program in linear fashion.
For Java, we have a static main, and we do not need a HelloWorld() constructor to initialize the HelloWorld object prior to making use of the main method.
Does the following program call a constructor? Perhaps a default constructor? Is an object of the StaticField class created and initialized?

What does line 27 do? Why don't we write something like the following?: CountInstances myCI = new CountInstances();

Let's situate the keyword static within the context of a discussion about methods.
myObject.methodOnThatObject();
myObject.propertyOnThatObject;
A class is both a compilation unit and a unit of encapsulation.
A class typically has members: methods, properties (instance variables), and
constructors.
Unlike a local variable, an instance variable is on every instance of an
object.
It is common to say, "This is a property
of the class", and "This is a property
on the object".
Objects have data (instance variables) and behavior (methods).
An instance variable is data that is also a property (also called an attribute or a field).
Static variables and methods are at the class level and independent of the creation of an instance of that class. Static variables are not re-created for each instance. Instead, they are already available when an instance comes into being.
Java does not support direct concatenation of methods in the way Unix shell scripting uses the pipe ( | ), which goes left to right.
ls -f | more
Instead of a data pipe running from left to right, think of communication, or
messages running, like Arabic numerals, from right to left.
like when you add starting from the right column, then moving to the column to
the left
356
+ 509
---------
You can pass the return value of one method as an argument to another method:
myObject.UseOutputOfAnotherMethod( myObject.MethodOnThatObject() );
Method nesting is unlimited:
myObject.UseOutputOfAnotherMethod( myObject.MethodOnThatObject( anotherObj.someMethod() );
The sequence of method calls goes from right to left, which is the mathematical norm.
In the following program, are the static methods called on a instance of the StaticBlock class?

Can a static method return a value?

Note: There is no static constructor because the meaning of static is that no constructor is necessary.