Serious Object Oriented Programming Basics by wpp15127

VIEWS: 22 PAGES: 62

									Chapter XIV

Serious OOP
Chapter XIV Topics
 14.1    Introduction
 14.2    OOP Terminology
 14.3    Default Constructors
 14.4    Accessing Attributes and Methods
 14.5    Constructor Overloading
 14.6    Accessing Multiple Files
 14.7    Set Methods
 14.8    Copy Constructors
 14.9    Scope of an Object
 14.10   Objects Are References
 14.11   Using the "this" Reference
 14.12   Nesting Classes with Composition
 14.13   Static Attributes and Methods
 14.14   The FishGfx class
 14.15   Summary




                                Chapter XIV   Serious OOP   14.1
14.1 Introduction

What kind of a chapter title is Serious OOP? Have we not been serious about
Object Oriented Programming before? Frankly, the whole OOP business with
Java presents some unique challenges in writing a textbook and teaching the topic.
Just take a look at this really simple program, in figure 14.1, which was one of the
first programs shown in the beginning of the course.


Figure 14.1
public class Java0202
{
  public static void main (String args[ ])
  {
    System.out.println("Plain Simple Text Output");
  }
}



At the first introduction of this short program you did not learn all of its features.
You did not know what a class was, why public or static is used and you did not
know anything about an args array. All you really learned was that it was
possible to display text with a println method, but then you also did not know
what a method was.

Languages like Pascal and C++ that support OOP are simpler to teach because it
is possible to ignore OOP in the beginning until such a time that it is desirable to
change gears and introduce Object Oriented Programming. Java has no such
comfort because every statement must be placed inside a class. Even the simplest
variable declaration or the shortest program, such as the one above, will require a
minimum of one class.



Important Java Reality

A Java program consists of one or more class
declarations. Every program statement must be
placed inside a class.



14.2   Exposure Java, 2007 Edition   08-18-07
It may be tricky to teach a programming language, like Java, where you feel that
everything needs to be introduced in the beginning, but that actually is one of it
appeals as a computer science introductory language. During the last couple of
decades, Object Oriented Programming has gained steady ground as the proper
approach to program design. It is possible with C++ to skirt around OOP or
postpone this OOP business for a considerable length of time. As you can tell by
our little program example in figure 14.1, you cannot even blow your nose in Java
without using a class.

A full-fledged treatment of OOP involves showing the encapsulation of data
(attributes) and methods (actions), but wait ... students do not know anything
about data types or variable declarations yet. In the very early chapters you
learned various concepts on faith. You were shown many Java program features,
told to use them and not ask too many questions with the promise that there will
be future explanations. As time went on, you learned more and more about
Object Oriented Programming and you have already seen a chapter on class
methods, object methods and inheritance.

So we now have the strange situation where you have already written many Java
programs, and all of these programs have used at least a little or perhaps a lot of
OOP features. There is a good chance that you have quite a good handle on many
of Java's OOP concepts and I hope that such is the case. At the same time there is
a lot left to be learned about this object business. This chapter is called Serious
OOP, because you now have the Java tools under your belt to take a serious look
at Object Oriented Programming. The majority of this chapter will review
concepts, which you have learned earlier and take a more thorough approach to
these topics. There will also be some new OOP issues presented.




14.2 OOP Terminology

There are people who believe that Object Oriented Programming is not so bad; it
is all this vocabulary that is hard to digest. This section will review the key OOP
terms without program examples. Many program examples will follow in the
remaining sections. Right now let us review the terminology that needs to be
second nature for any serious Java programmer. Some definitions that follow may
not be very clear to you. Perhaps you never understood their meaning at the first
introduction, and maybe it still does not make sense with this review presentation.
Well do not give up. You will hear this terminology used very frequently and the


                                                 Chapter XIV   Serious OOP    14.3
nature of vocabulary is that a clear understanding comes from using words in the
proper context. The main purpose right now is to summarize the language that
will be used in this chapter and future Exposure Java chapters.


Program Modules

Program development requires that large programs are divided
into smaller program modules to be manageable. This is the
principle of divide and conquer.



Structured Programming

Structured programming is an organized style of
programming that places emphasis on modular programming,
which aids testing, debugging and modifying.

In structured programming, modules are procedures and
functions that process external data passed by parameters.



Object Oriented Programming, a Casual Definition

Object Oriented Programming is a programming style with
heavy emphasis on program reliability through modular
programming.

In object oriented programming, modules contain both the data
and subroutines that process the data. In Java the modules
are called classes and the process-subroutines are smaller
modules called methods.




14.4   Exposure Java, 2007 Edition   08-18-07
Object Oriented Programming, a formal definition

Object Oriented Programming is a style of programming
that incorporates program development in a language
with the following three OOP traits:

 Encapsulation
 Polymorphism
 Inheritance



Encapsulation

Encapsulation is the process of placing a data structure’s
data (attributes) with the methods (actions) that act upon
the data, inside the same module, called a class in Java.



Inheritance

Inheritance is the process of using features (both attributes
and actions) from an established higher class. The higher
class is called the superclass. The lower class is called the
subclass.



Polymorphism

Polymorphism allows a single accessing feature, such as an
operator, method or class identifier, to have many forms.
This is hardly a clear explanation. Since the word
polymorphism is used in the formal OOP definition, a brief
explanation is provided, but details of this powerful OOP
concept will come in a later chapter.



                                      Chapter XIV   Serious OOP   14.5
Class

A class is a user-defined data type that encapsulates both data
and the methods that act upon the data. A class is a template
for the construction of objects.



Object or Instance

An object is one instance of a class. A class is a type and an
object is a variable. Cat is a class and Fluffy is an object or
one instance of the Cat class.

Objects can be discussed in a general sense, such as in
Object Oriented Programming. This causes confusion
between Object, the concept and object, the instance of a
class. There is a tendency to use instance when referring to
one variable example of a class to avoid confusion.



Attributes or Instance Variables

The data components of a class are the class attributes and
they are also called instance variables. Instance variables
should only be accessed by methods of the same class.



Methods

Methods are action modules that process data. In other
languages such modules may be called subroutines,
procedures or functions. In Java the modules are called
methods. They are declared inside a class module and
process the instance variables.




14.6   Exposure Java, 2007 Edition   08-18-07
Instantiation

Instantiation is the moment or instance that memory is
allocated for a specific object of a class. Statements like the
construction of an object, the definition of an object, the
creation of an object all have the same meaning as the
instantiation of an object.



This is by no means a complete list of OOP terminology. The definitions
presented in this section represent most of the general terms. Specific terms like
set method, static method, this reference, etc. will be explained within their own
respective section along with functional program examples that help to explain the
meaning of the concept.




14.3 Default Constructors

I like using case studies to teach complex topics. Case studies present concepts in
a series of programs that represent the steady growth of a program as it develops
through growing stages from the simplest start to the complex final program.
Case studies are a popular approach in teaching computer science and have been
used for many years. In this chapter a case study will be started that will continue
in a future chapter. You have seen explanations about OOP using a previous
Piggy class and a CardDeck class. This time we will look at a Person class. As
you look at the program examples that follow, you will find that each stage
increments the number of the Person class. It starts with Person01 and then
continues with Person02, Person03 and so on. This approach makes it easier to
explain comparisons between different Person class stages. It also makes
compiling the programs simpler. If every program uses the same identifier, the
result will be that each successive program overrides the Person.class file of the
previous program.

A person is an object with many attributes and many behaviors. Attributes
include name, birthdate, height, weight, parents, children, eye color, education,
marital status, hobbies, and many others. Behaviors include displaying the values


                                                  Chapter XIV   Serious OOP    14.7
of all attributes along with going to school, getting married, buying a house, going
on vacation, taking a shower, getting dressed, sleeping, walking, running, eating,
and on goes the list.

Our Person class will not be so ambitious to include a large list of attributes and
methods. There will only be a minimal list that is sufficient to illustrate a variety
of OOP concepts. In fact, our Person class starts off with three modest attributes,
which are name, yearBorn and education.

You will note in program Java1401.java, shown in figure 14.2, that there are two
class declarations. There is the customary program name class declaration,
Java1401, and the Person01 class declaration. Every executable application
program needs at least one class, and that class needs to contain the main method.
The main method will always be a static method and the main method uses a
String array parameter that can be used for command line input.

If you look at demonstration programs provided by a variety of Java sources you
will find that it is customary to create one file for one class. A practical class in
the real world can be quite large and multiple classes in one program cause
considerable complexity. Later in this chapter you will be shown how to manage
multiple files into a single program. Right now it is easier to show two small
classes in the same program file.

Figure 14.2
// Java1401.java
// Stage-1 of the Person class.
// Only the Person class data attributes are declared. Each stage of the Person class will have its own
// number to distinguish between the different stages.


public class Java1401
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 1\n");
         Person01 p = new Person01();
         System.out.println();
    }
}


class Person01
{
    String name;
    int yearBorn;
    int education;
}



                                                                              Java1401.java Output

Person Class, Stage 1




14.8     Exposure Java, 2007 Edition             08-18-07
Let us make some important observations about the Person class declaration.
You need the Java reserved word class followed by a class identifier. The class
body is placed between opening and closing braces. Class attributes are declared
inside the class body in the data-type followed by variable identifier format.

Notice how the Person class module is declared outside the Java1401 class
module. If you declare Person inside Java1401 you may find that you get some
bizarre results, like an output that continues on and on until it gets stopped by an
error message. Java allows a class to be declared inside another class and calls
this an Inner Class. Explaining inner classes will follow in a later chapter.


Class Declaration Location

In most cases a class declaration is located outside any other
class declaration. It is possible to declare one class inside
another class (inner class), which will be explained later.



The Person01 class has no process capabilities. It only contains attributes. The
program output consists of output generated by the main method of the Java1401
class. Nothing is contributed by Person01. A p object is in fact instantiated and
that is done primarily to demonstrate that it is possible to compile a class that
stores only data. Program Java1402.java, in figure 14.3, adds a constructor to the
Person02 class.



Instantiation and Construction

An object is created with the new operator. The creation
of a new object is called:
           instantiation of an object
           construction of an object

The special method that is called during the instantiation of
a new object is called a constructor.




                                                  Chapter XIV   Serious OOP    14.9
Figure 14.3
// Java1402.java
// Stage-2 of the Person class.
// This stage adds a default "no-parameter" constructor to the Person class.


public class Java1402
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 2\n");
         Person02 p = new Person02();
         System.out.println();
    }
}

class Person02
{
    String name;
    int yearBorn;
    int education;

    Person02()
    {
       System.out.println("Calling Default Constructor");
       name = "John Doe";
       yearBorn = 1980;
       education = 0;
    }

}



                                                                               Java1402.java Output

Person Class, Stage 2

Calling Default Constructor




There is evidence that the only method in Person02 must be called. The program
output shows the statement Calling Default Constructor and such a statement is
only shown inside the constructor method. Constructor methods are somewhat
odd. For starters, constructor methods are neither void methods nor return
methods. A constructor is not called in a stand-alone statement with the method
identifier, and it is not called in a program statement that uses a value that is
provided by a return method. A constructor is called by the new operator in a
statement like:

                           Person02 p = new Person02();

The use of constructors is one terrific feature in OOP that greatly adds to
reliability. Variables require values. Failure to initialize a variable with an
appropriate value can cause program logic errors during execution. An object of a
complicated class has many attributes that all need to start with a proper value.
One important job of a constructor is to initialize every instance variable of the


14.10      Exposure Java, 2007 Edition            08-18-07
new object with some appropriate value. The more general purpose of a
constructor is to make an object ready to be used during program execution. Such
a task may require considerably more processing than simply assigning initial
values. You may remember the example of the CardDeck class, which included
shuffling the cards when a new CardDeck object was instantiated.

What happens when you do not include a constructor method with a new class
declaration? In such a case, Java still calls a constructor and tries to do a good job
making your object ready for use. The reality is that you have lost control over
your program. This is not good OOP design.



Constructor Notes

A constructor is a method with the same identifier as the class.
Constructors are neither void nor return methods.
A constructor is called during the instantiation of an object.
Constructors without parameters are default constructors.




14.4 Accessing Attributes and Methods

In the old Pre-OOP days there were data structures that stored data and there were
modules, called subroutines, procedures or functions that accessed the data
directly. This was normally done with parameter passing. As programs grew in
size and complexity, it became harder and harder to control proper data access. It
was very common that one procedure altered variable values in such a way that is
caused problems for the proper processing of another procedure. The biggest
problem is that special procedures that would insure proper handling of data were
either not used or could be bypassed very easily.

Is it such a big deal that data is handled in a special way? There certainly are
many examples of simple programs, like the ones used in this chapter, where it is
easy to control proper program execution. It is with complex programs that OOP
assists by accessing data properly. Consider a practical example outside the
computer program world. A bio-lab is processing dangerous organisms in an


                                                  Chapter XIV   Serious OOP     14.11
effort to find cures for serious diseases. A special environment is created that
seals the deadly bacteria inside a container. Can a lab technician reach inside the
container to handle the bacteria? Certainly not, such an action may kill the lab
technician and potentially start a serious epidemic. In such a case there are special
robotic arms that control the handling of the bacteria. The lab technician uses
joysticks outside the bio container to manipulate the robot arms.

Your programs will not cause deadly epidemics if you do not create special
accessing methods to handle data but the malfunction of programs has caused,
major loss of money and yes sometimes ... death and injury to people. The
Denver International Airport opened during the mid Nineties, six months behind
schedule. The highly sophisticated computer program that handled the luggage
system was flawed. The airport lost millions of dollars because of the late
opening, all caused by the malfunctioning of a computer program.

Program Java1403.java, in figure 14.4, is a stage in the Person class that shows a
very serious nono. The instance variables of the Person object are accessed
directly without using any special methods. You will find that the program works
correctly, but keep in mind that this is a very small program. What you see
demonstrated here is a total violation of the encapsulation principle.


Figure 14.4
// Java1403.java
// Stage-3 of the Person class.
// This stage accesses Person data directly, which is very poor OOP design
// by violating encapsulation, which may cause side effects.

public class Java1403
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 3\n");
         Person03 p = new Person03();
         System.out.println("Name:        " + p.name);
         System.out.println("Born:        " + p.yearBorn);
         System.out.println("Education: " + p.education);
         System.out.println();
    }
}

class Person03
{
    String name;
    int yearBorn;
    int education;

    Person03()
    {
       System.out.println("Calling Default Constructor");
       name = "John Doe";
       yearBorn = 1980;
       education = 0;
    }

}




14.12      Exposure Java, 2007 Edition             08-18-07
Figure 14.4 continued
                                                                             Java1403.java Output
Person Class, Stage 3

Calling Default Constructor
Name:       John Doe
Born:       1980
Education: 0




As you see, it is possible to use the object name, p in this case, and access the data
by using a dot followed by the attribute identifier. Perhaps you are convinced that
this is a bad thing and you are surprised that a prominent language such as Java,
and a powerful programming feature, such as OOP, allows this bad style of
programming. Yes it is possible to write a program in this manner, but Java
includes some special protection to prevent improper access of instance variables.
Program Java1404.java, in figure 14.5, adds two very important reserved words:
private and public. The data attributes are declared as private and the methods
are declared as public.         Program Java1404.java is almost identical to
Java1403.java. Only the reserved Java keywords public and private have been
added. The improper data access, which was possible in the previous program, is
now blocked and the compiler indicates three compile errors. There is one error
for each attempted access to private data.


Figure 14.5
// Java1404.java
// Stage-4 of the Person class. In this program direct access to Person data is denied by declaring
// all class data private. This program will not compile.

public class Java1404
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 4\n");
         Person04 p = new Person04();
         System.out.println("Name:        " + p.name);
         System.out.println("Year Born: " + p.yearBorn);
         System.out.println("Education: " + p.education);
         System.out.println();
    }
}

class Person04
{
    private String name;
    private int yearBorn;
    private int education;

    public Person04()
    {
        System.out.println("Calling Default Constructor");
        name = "John Doe";
        yearBorn = 1980;
        education = 0;
    }
}



                                                                 Chapter XIV        Serious OOP       14.13
Figure 14.5 continued
                                                                            Java1404.java Output

Java1404.java:28: Name has private access in Person04
      System.out.println("Name:       " + P.Name);
                                            ^
Java1404.java:29: YearBorn has private access in Person04
      System.out.println("Year Born: " + P.YearBorn);
                                          ^
Java1404.java:30: Education has private access in Person04
      System.out.println("Education: " + P.Education);
                                            ^
3 errors




Program Java1405.java, in figure 14.6, adds three return methods. Each method
returns the value of one of the data attributes. Now the previous program caused a
compile error when some client of the Person class attempted access to the
private data. You might expect the same problem here. This program works just
fine and the difference is that the client, Java1405 in this case, accesses the public
methods, getYearBorn, getName and getEducation, and those methods in turn
access the private data. It is a little like a bank. You access the bank teller, and
the bank teller accesses the money in the bank. You do not help yourself to the
money in the bank.

Figure 14.6
// Java1405.java
// Stage-5 of the Person class.
// The private data of the Person class is now accessed with public member "get methods" of the Person class.

public class Java1405
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 5\n");
         Person05 p = new Person05();
         System.out.println("Name:        " + p.getName());
         System.out.println("Year Born: " + p.getYearBorn());
         System.out.println("Education: " + p.getEducation());
         System.out.println();
    }
}

class Person05
{
    private String name;
    private int yearBorn;
    private int education;
    public Person05()
    {
        System.out.println("Calling Default Constructor");
        name = "John Doe";
        yearBorn = 1980;
        education = 0;
    }
    public int getYearBorn()     { return yearBorn; }
    public String getName()      { return name; }
    public int getEducation()    { return education; }
}



14.14      Exposure Java, 2007 Edition             08-18-07
Figure 14.6 continued
                                                           Java1405.java Output
Person Class, Stage 5

Calling Default Constructor
Name:      John Doe
Year Born: 1980
Education: 0




Private and Public Class Members
The principle of encapsulation requires that object data
members are only accessed by methods of the same object.
Private class members of some object x can only be accessed
by methods of the same x object.
Public class members of some object x can be accessed by
any client of object x.
Data attributes of a class should be declared private.
Methods of a class are usually declared public, but there are
special helper methods that may also be declared private.
Helper methods will be demonstrated later in this chapter.




14.5 Constructor Overloading

Default constructors lack flexibility. Each object is instantiated with a default
constructor that gets the same plain-vanilla treatment. The default constructor is
the constructor you get when there is no indication that you want some specialized
instantiation. It is possible to create multiple methods all with the same identifier
as long as the parameter heading is different. This is called a different signature,
so that the compiler can make a distinction between the like-named methods.
This is one example of polymorphism, and this is normally called overloaded
methods. There is quite a bit more to polymorphism that will be explained later.
In program Java1406.java, shown in figure 14.7, the second, overloaded,


                                                 Chapter XIV    Serious OOP    14.15
constructor has three parameters, one for each one of its data attributes. At the
instantiation of a new object, specific information can be passed to the constructor
to create an object with the desired name, yearBorn and education. Both
constructors will be used in this program example.

Figure 14.7
// Java1406.java
// Stage-6 of the Person class. This stage adds a second "parameter-constructor" to the Person class.

public class Java1406
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 6\n");
         Person06 p1 = new Person06();
         System.out.println("Name:       " + p1.getName());
         System.out.println("Year Born: " + p1.getYearBorn());
         System.out.println("Education: " + p1.getEducation());
         System.out.println();
         Person06 p2 = new Person06("Sue",1972,16);
         System.out.println("Name:       " + p2.getName());
         System.out.println("Year Born: " + p2.getYearBorn());
         System.out.println("Education: " + p2.getEducation());
         System.out.println();
    }
}

class Person06
{
    private String name;
    private int yearBorn;
    private int education;
    public Person06()
    {
        System.out.println("Calling Default Constructor");
        name = "John Doe";
        yearBorn = 1980;
        education = 0;
    }
    public Person06(String n, int y, int e)
    {
        System.out.println("Calling Parameter Constructor");
        name = n;
        yearBorn = y;
        education = e;
    }
    public int getYearBorn()     { return yearBorn; }
    public String getName()      { return name; }
    public int getEducation()    { return education; }
}


                                                                            Java1406.java Output
Person Class, Stage 6

Calling Default Constructor
Name:       John Doe
Year Born: 1980
Education: 0

Calling Parameter Constructor
Name:       Sue
Year Born: 1972
Education: 16



14.16     Exposure Java, 2007 Edition             08-18-07
14.6 Accessing Multiple Files

Students in a first-year computer science course have difficulty imagining the
share size and complexity of programs in the industrial world. In the late
Seventies I was associated with airline reservation software and even in those
relatively early days of computer use, the software exceeded two-million lines of
programming. Can you imagine how long it takes to compile a program that is
two million lines in length? We do not even want to talk about writing a program
that length. Now consider that you make a small error somewhere or you make
some small addition. Would it not be horrendous to have to compile so many
lines of code for one small error or some small addition to the program?

For years now, programs have had the ability to divide the complete program into
separate files that can be individually compiled and then linked together during
program execution. This is also terrific for a large program that is written by a
team of programmers with each programmer responsible for a small segment of
the whole project.

Different languages use different approaches in subdividing a program into
multiple files, which can be compiled separately. The customary approach in Java
is to create one file for one complete class. This is shown with the next example.
Program Java1407.java is the same as the previous program with a sequence
number change. However, the program is now divided up into the Java1407.java
file, shown in figure 14.8 and the Person07.java file, shown in figure 14.9.


Figure 14.8
// Java1407.java
// Stage-7 of the Person class.
// This program shows how a program can be separated into multiple files,
// which in this case are the Person07.java and Java1407 files.
// The result is the same as the Java1406.java program.

public class Java1407
{
    public static void main(String args[])
    {
         System.out.println("Person Class, Stage 7\n");
         Person07 p1 = new Person07();
         System.out.println("Name:       " + p1.getName());
         System.out.println("Year Born: " + p1.getYearBorn());
         System.out.println("Education: " + p1.getEducation());
         System.out.println();
         Person07 p2 = new Person07("Sue",1972,16);
         System.out.println("Name:       " + p2.getName());
         System.out.println("Year Born: " + p2.getYearBorn());
         System.out.println("Education: " + p2.getEducation());
         System.out.println();
    }
}




                                                                  Chapter XIV   Serious OOP   14.17
Figure 14.9
// Person07.java
// This file supports the executable Java1407.java file.


public class Person07
{
    private String name;
    private int yearBorn;
    private int education;

    public Person07()
    {
        System.out.println("Calling Default Constructor");
        name = "John Doe";
        yearBorn = 1980;
        education = 0;
    }

    public Person07(String n, int y, int e)
    {
        System.out.println("Calling Parameter Constructor");
        name = n;
        yearBorn = y;
        education = e;
    }

    public int getYearBorn()     { return yearBorn; }
    public String getName()      { return name; }
    public int getEducation()    { return education; }
}



                                                               Java1407.java Output

Person Class, Stage 7

Calling Default Constructor
Name:       John Doe
Year Born: 1980
Education: 0

Calling Parameter Constructor
Name:       Sue
Year Born: 1972
Education: 16




The two program files each need to be compiled separately. This will result in
two bytecode files. Actually, the previous program, which contained the same
two classes also created two bytecode files, but that never seemed to be much of
an issue. The main point is that when the program is executed with the driving
class containing the main method, there must be a bytecode file for each class in
the program. Make sure that all the files are in the same folder or subdirectory.
This is one reason people like the fancier Java Integrated Development
Environments (IDEs), which keep track of all the necessary file locations.




14.18      Exposure Java, 2007 Edition              08-18-07
Working with Multiple Files

Create a separate file for each class in the program or at least
a file that is manageable in size with several small classes.
Make sure there is only one file with a main method, known as
the main file or driver class.
Place all the files in the same folder and compile the driver
class, which will result in compiling all other classes, or compile
each file separately.
Execute the entire program by executing the main driver class.



Programming with separate files has many advantages. One major advantage is
that a class can be thoroughly tested and then tucked away, pre-compiled, and
ready for use when it is linked with all the other files.

You have already seen various program examples that use the import statement at
the start of a program. This statement indicates that a pre-compiled Java package
needs to be included. This is really the same concept as is shown in this section.
You have just been shown how to divide a program into separate files, compile
them separately and then execute everything together. This all works fine with the
provision that every file is in the same specified location. With the import
statement it is possible to have access to files in other locations.




14.7 Set Methods

There will be many more program examples with the Person class and each one
of those examples will use the separate file approach. This means that as you
view the execution output of these files, you will need to compile two files for
each program. If you use the Command Line Prompt compile method, shown at
the start of the course, you can speed up compiling by using the statement javac
Person??.java, which will compile all the Person files in one command. You
can also automatically compile all the necessary files for one program by


                                               Chapter XIV   Serious OOP    14.19
compiling the file with the main method. All the supporting files will be
compiled automatically, provided they are located in the same folder.

Many programs have interactive data entry. Data is not entered once by a default
constructor or some parameter constructor, but dynamically during the execution
of a program. Yes, it is still important to construct objects with initial values, but
there must also be ways to alter existing data values of an object.

With a correct encapsulation principle in mind, you know that it is wrong to
access and alter the data attributes of any object directly. You have seen special
methods, called getMethods, that access and return the values of private data.
Now we need to look at a group of methods, called setMethods, which access and
modify the values of instance variables.

Program Java1408.java, in figure 14.10, constructs a Person object with a
default constructor and displays the data values of the object with the showData
method. The program then continues by prompting for interactive input during
program execution for each data attribute. Each value as it is entered, is stored in
the object with the setName, setYearBorn and the setEducation methods. The
additional setMethods are used by the Java1408 class, but they are added to the
Person08 class, in figure 14.11.


Figure 14.10
// Java1408.java
// Stage-8 of the Person class.
// This stage adds "setMethods" that alter private data of a class during
// program execution. It also adds a showData method to display all the
// data with a single call.


import java.util.Scanner;


public class Java1408
{
    public static void main (String args[])
    {
         Scanner input = new Scanner(System.in);

        System.out.println("Person Class, Stage 8\n");
        Person08 p = new Person08();
        p.showData();

        System.out.print("Enter name      ===>> ");
        p.setName(input.nextLine());
        System.out.print("Enter year born ===>> ");
        p.setYearBorn(input.nextInt());
        System.out.print("Enter education ===>> ");
        p.setEducation(input.nextInt());
        System.out.println();

        p.showData();
    }
}




14.20      Exposure Java, 2007 Edition             08-18-07
Figure 14.11 Continued
// Person08.java
// This file supports the Java1408.java executable file.


public class Person08
{

    ///// PRIVATE PERSON ATTRIBUTES ////////////////////////////////////////////////////
    private String name;
    private int yearBorn;
    private int education;

    ///// CONSTRUCTORS ////////////////////////////////////////////////////////////////
    public Person08()
    {
          System.out.println("Calling Default Constructor");
          name = "John Doe";
          yearBorn = 1980;
          education = 0;
    }

    public Person08(String n, int y, int e)
    {
        System.out.println("Calling Parameter Constructor");
        name = n;
        yearBorn = y;
        education = e;
    }

    ///// GET (ACCESSOR) METHODS ////////////////////////////////////////////////////////
    public String getName()       { return name; }
    public int getYearBorn()      { return yearBorn; }
    public int getEducation()     { return education; }
    public void showData()
    {
          System.out.println("Name:        " + getName());
          System.out.println("Year Born: " + getYearBorn());
          System.out.println("Education: " + getEducation());
          System.out.println();
    }

    ///// SET (MODIFIER) METHODS ////////////////////////////////////////////////////////
    public void setYearBorn(int y)   { yearBorn = y; }
    public void setName(String n)    { name = n; }
    public void setEducation(int e)  { education = e; }

}




Notice how the Person08.java file is organized. The Person08 class starts with
the private data declarations, followed by constructors and then the getMethods
and the setMethods. Each group of class members is commented to help the
readability of the class for testing, debugging and later modification. This file
actually does not even have many comments. A well-documented file includes
comments explaining each individual method. The methods in this example are
so short and simple that the method identifier, like getName, is sufficient to
explain the purpose of the method.




                                                                                  Chapter XIV   Serious OOP   14.21
Figure 14.11 Continued
                                                                              Java1408.java Output

Person Class, Stage 8

Calling Default Constructor
Name:         John Doe
Year Born:    1980
Education:    0

Enter name                      ===>>       Byron Derry
Enter year born                 ===>>       1966
Enter education                 ===>>       20

Name:                  Byron Derry
Year Born:             1966
Education:             20




14.8 Copy Constructors

For various reasons it may be desirable to construct a new object as a copy of an
existing object. It is possible to use the getMethods of a class to access the values
of some existing object. With these newfound values a second object can be
constructed that is a copy of the first object. Now it sure would be more efficient
if a second object could be constructed using the first object as a parameter. Is
this possible? Take a look at Java1409.java, in figure 14.12, and see what
happens with such an approach.

Figure 14.12
// Java1409.java
// Stage-9 of the Person class. This stage attempts to create a copy with an existing object at the parameter
// for the constructor of the second object.

public class Java1409
{
    public static void main (String args[])
    {
         System.out.println("Person Class, Stage 09\n");
         Person09 p1 = new Person09("Seymour",1975,18);
         p1.showData();
         Person09 p2 = new Person09(p1);
         p2.showData();
    }
}




14.22     Exposure Java, 2007 Edition             08-18-07
Figure 14.12 Continued
                                                                                           Java1409.java Output

Java1409.java:14: cannot resolve symbol
symbol : constructor Person09 (Person09)
location: class Person09
      Person09 p2 = new Person09(p1);
                    ^
1 error




It does not take long to see that Java is displeased and you get a lovely error
message. If you cleverly tried to compile all the programs at once in this chapter,
you will be happy to know that this intentionally wrong program will mess up
your shortcut desires. Now some of you have C++ knowledge and you know this
should work. Well wake up and smell the coffee, because this is Java, and not
C++. What works for one language does not necessarily work for another
language.

You also know that this section does not exist for the single purpose of showing a
neat feature that does not work. You can use an object as a parameter for the
instantiation of a second object, but you need to create a copy constructor.
Program Java1410.java, in figure 14.13, works just fine. You will not see any
difference there because the change is in the Person10.java class, shown in figure
14.14, which includes a brand-new copy constructor.


Figure 14.13
// Java1410.java
// Stage-10 of the Person class.
// This stage attempts to create an copy with an existing object
// at the parameter for the constructor of the second object.
// This time a "copy constructor" has been added to the Person class.

public class Java1410
{
    public static void main (String args[])
    {
         System.out.println("Person Class, Stage 10\n");
         Person10 p1 = new Person10("Seymour",1975,18);
         p1.showData();
         Person10 p2 = new Person10(p1);
         p2.showData();
    }
}



Figure 14.14
// Person10.java
// This file supports the Java1410.java executable file.

public class Person10
{
    ///// PRIVATE PERSON ATTRIBUTES ////////////////////////////////////////////////////
    private String name;




                                                                          Chapter XIV         Serious OOP   14.23
    private int yearBorn;
    private int education;

    ///// CONSTRUCTORS ////////////////////////////////////////////////////////////////
    public Person10()
    {
          System.out.println("Calling Default Constructor");
          name = "John Doe";
          yearBorn = 1980;
          education = 0;
    }

    public Person10(String n, int y, int e)
    {
        System.out.println("Calling Parameter Constructor");
        name = n;
        yearBorn = y;
        education = e;
    }

    public Person10(Person10 p)
    {
        System.out.println("Calling Copy Constructor");
        name = p.name;
        yearBorn = p.yearBorn;
        education = p.education;
    }


    ///// GET (ACCESSOR) METHODS ////////////////////////////////////////////////////////
    public String getName()           { return name; }
    public int getYearBorn()          { return yearBorn; }
    public int getEducation()         { return education; }
    public void showData()
    {
          System.out.println("Name:        " + getName());
          System.out.println("Year Born: " + getYearBorn());
          System.out.println("Education: " + getEducation());
          System.out.println();
    }

    ///// SET (MODIFIER) METHODS ////////////////////////////////////////////////////////
    public void SetYearBorn(int y)   { yearBorn = y; }
    public void SetName(String n)    { name = n; }
    public void SetEducation(int e)  { education = e; }

}




Figure 14.14 Continued
                                                                                            Java1410.java Output

Person Class, Stage 10

Calling Default Constructor
Name:         Seymour
Year Born:    1975
Education:    18

Calling Copy Constructor
Name:         Seymour
Year Born:    1975
Education:    18




14.24       Exposure Java, 2007 Edition                        08-18-07
Copy Constructor

  public Person10(Person10 p)
  {
    System.out.println("Calling Copy Constructor");
    name = p.name;
    yearBorn = p.yearBorn;
    education = p.education;
  }

A copy constructor is a constructor that instantiates a new
object as a copy of an existing object. A copy constructor uses
a single parameter, which is an object of the same class as the
copy constructor.


Perhaps you cannot think of a practical situation where a copy constructor would
work. In today's technology, network administration is all around us. Different
network users have different rights, and network-access-rights can be quite
complex. It is possible to create a new network user that has the same rights as an
existing network user. The network administration program, which works in the
background to make this possible, may very well be using a copy constructor
when a new network user is created equal to some existing user.




14.9 Scope of an Object

Objects do not necessarily exist from instantiation to the conclusion of program
execution. Objects, like all variables have scope. What is scope? The scope of a
variable - simple or object - is the period during which a variable is defined and
has allocated memory to store values. Program Java1411.java, in figure 14.15, is
divided into various block levels to demonstrate object scope. You will note
some commented program statements. These statements attempt to access the p1,
p2 and p3 objects when they are no longer in scope. When you remove these
comments Java will not compile, because objects are accessed, which are no
longer alive.




                                                Chapter XIV   Serious OOP    14.25
Figure 14.15
// Java1411.java
// Stage-11 of the Person class.
// The Person class has been simplified to demonstrate scope of an object.
// The program will only compile with several statements commented out. Remove the
// comments and the program does not compile, because the objects are no longer in scope.


public class Java1411
{
    public static void main (String args[])
    {
         System.out.println("Person Class, Stage 11\n");
         System.out.println("MAIN, LEVEL 1");
         Person11 p1 = new Person11("Kathy");
         p1.showData("p1");
         {
             System.out.println("\nMAIN, LEVEL 2");
             Person11 p2 = new Person11("Joseph");
             p2.showData("p2");
             {
                 System.out.println("\nMAIN, LEVEL 3");
                 p1.showData("p1");
                 p2.showData("p2");
                 Person11 p3 = new Person11("Elizabeth");
                 p3.showData("p3");
             }
             System.out.println("\nMAIN, LEVEL 2");
             p1.showData("p1");
             p2.showData("p2");
//           p3.showData("p3");
         }
         System.out.println("\nMAIN, LEVEL 1");
         p1.showData("p1");
//       p2.showData("p2");
//       p3.showData("p3");
         System.out.println();
    }
}




                                                                          Java1411.java Output
Person Class, Stage 11

MAIN, LEVEL 1
showData for: p1                Name:       Kathy

MAIN, LEVEL 2
showData for: p2              Name:       Joseph

MAIN, LEVEL 3
showData for: p1                Name:       Kathy
showData for: p2                Name:       Joseph
showData for: p3                Name:       Elizabeth

MAIN, LEVEL 2
showData for: p1                Name:       Kathy
showData for: p2                Name:       Joseph

MAIN, LEVEL 1
showData for: p1                Name:       Kathy




14.26     Exposure Java, 2007 Edition           08-18-07
14.10 Objects Are References

For many chapters you have used simple or primitive data types. You learned that
a variable or a simple data type is a location in memory. When you access the
memory location, by using the variable name, you get the value stored at the
indicated memory location. With data structures the story changes and primarily
you have viewed the output of data structures members by using access methods,
which return the value of object attributes. Essentially, you are still looking at the
values of simple data types. It is just more complicated, because you now see that
data is contained inside an object.

So is the value of an object not definable? After all, an object can contain one of
more data members, along with some friendly methods to manipulate the data.
Have patience, because there is a point to this odd-sounding digression. It is not
particularly shocking to assign the value of one variable to another variable of the
same data type. This process is precisely what is demonstrated by program
Java1412.java, shown in figure 14.16. The program example features two
objects of the Person class and two variables of the int type. Check out the
program briefly and then move on to see the program output.

Figure 14.16
// Java1412.java
// This program demonstrates the side effect caused by the p2 = p1;
// statement. Note that p1 is altered after p2 is altered.


public class Java1412
{
    public static void main (String args[])
    {
         System.out.println("\nJava1412.java\n");
         Person p1 = new Person("Kathy");
         p1.showData("p1");
         Person p2 = new Person("Tom");
         p2.showData("p2");
         p2 = p1;
         p2.showData("p2");
         p2.setName("George");
         p2.showData("p2");
         p1.showData("p1");

        System.out.println();
        int num1 = 15;
        System.out.println("num1: " + num1);
        int num2 = 25;
        System.out.println("num2: " + num2);
        num2 = num1;
        System.out.println("num2: " + num2);
        num2 = 100;
        System.out.println("num2: " + num2);
        System.out.println("num1: " + num1);
        System.out.println();
    }
}




                                                               Chapter XIV   Serious OOP   14.27
class Person
{
    private String name;

    public Person(String n)
    {
        name = n;
    }

    public void showData(String s)
    {
        System.out.println("showData for: " + s + " has name " + name);
    }

    public void setName(String n)
    {
        name = n;
    }

}



Figure 14.16 Continued
                                                                          Java1412java Output

Java1412.java

showData        for:   p1     has   name   Kathy
showData        for:   p2     has   name   Tom
showData        for:   p2     has   name   Kathy
showData        for:   p2     has   name   George
showData        for:   p1     has   name   George

num1:     15
num2:     25
num2:     15
num2:     100
num1:     15




The output of Java1412.java shows some peculiar results. At least it is peculiar in
the object department. Objects p1 and p2 are each instantiated with a specified
name value. The values are displayed and then p1 is assigned to p2. Again the
values of the objects are displayed and everything still checks out. Now it
becomes weird. Object p2 is assigned a new name and somehow this new name
is not only assigned to p2, but it is also assigned to p1.

A similar set of program statements is used with int variables num1 and num2
without any unusual results. Changing the value of num2 has no impact on the
value of num1. There is something peculiar going on, and this peculiarity needs
to become crystal clear in your brain. It will prevent many future programming
headaches when dealing with objects.




14.28     Exposure Java, 2007 Edition            08-18-07
Your original view of data, and the storage of data values in memory, is correct.
You create two integer variables and each variable is allocated its own private
block of memory. The value of one integer may be copied to another integer
without problem. However, changing one integer should not alter the value of the
second integer. This perception is correct, at least for primitive data types. You
see the proof of it with num1 and num2 in Java1412.java.

Understanding how objects behave will require another program example.
Program Java1413.java, in figure 14.17, constructs two Person objects. You will
observe that the new operator is used twice. With each use of new, memory is
found and allocated for the new object. Two objects mean two sets of memory.
To verify that this is happening, the value of each object is displayed. This may
seem odd. You are not looking at the value of data stored in an object, but rather
the value of the object itself. This does compile and has some interesting results.


Figure 14.17
// Java1413.java
// This program demonstrates that an object stores the memory address where the object data is located.
// It does not store the data. When one object is assigned to another object, only the address is copied.


public class Java1413
{
    public static void main (String args[])
    {
         System.out.println("\nJava1413.java\n");
         Person p1 = new Person();
         Person p2 = new Person();
         System.out.println("p1 value: " + p1);
         System.out.println("p2 value: " + p2);
         p2 = p1;
         System.out.println("\np2 value: " + p2);
         System.out.println();
    }
}

class Person
{
    private String name;

    public Person()
    {
        name = "John Doe";
    }
}



                                                                               Java1413java Output

Java1413.java

p1 value:         Person@df6ccd
p2 value:         Person@601bb1

p2 value:         Person@df6ccd




                                                                Chapter XIV        Serious OOP          14.29
The output does not display anything of a civilized value, at least not civilized by
your experience standards. It looks more like some strange type of email address.
You are looking at actual memory values. The output starts with the name of the
class, Person, followed by the address of the object. The @ symbol indicates
address. You may not actually understand why there is an address displayed for
object values, but you do see two different addresses for p1 and p2. At least, the
addresses are different until the p2 = p1 statement. After that statement both
objects have the same memory address.

But why is there a memory address? You probably expected some type of Person
data information, like name. What good is it to store a memory address? The
answer to that question is not easily explained. Figure 14.18 is a symbolic
representation of various memory locations in the computer's RAM.


Figure 14.18

         p1                    p2                         num1
         @dff6ccd              @601bb1                    15
         dd

                                                          num2
                                                          25
              dff6ccd               601bb1

         Kathy                 Tom




The values used by the earlier Java1412.java are used. Note how the value of p1
and p2 is the memory address where the actual object information, Kathy and
Tom, is stored. On the other hand, num1 and num2 store int values 15 and 25
directly. Figure 14.19 shows the result of making the two assignment statements:

                                   p2 = p1;
                                 num2 = num1;

There are few surprises in the num1 and num2 department. Both locations now
contain the value 15. Objects p1 and p2 store memory references to the actual
locations where object information is stored. The consequence of assigning p1 to
p2 is that both objects now store the same memory reference. This also means that
indirectly both p1 and p2 now reference Kathy.



14.30   Exposure Java, 2007 Edition   08-18-07
Figure 14.19

        p1                    p2                        num1
        @dff6ccd              @dff6ccd                  15


                                                       num2
                                                        15
             dff6ccd               601bb1

         Kathy                Tom




Objects and Simple Types Store Information Differently

Simple (primitive) data types store assigned values directly in
their allocated memory locations.

Objects store memory references of the memory locations
allocated during the construction of the object.



In the final step of program Java1412.java the values of p2 and num2 were
altered. This is where the results were unexpected, at least on the object side.
Figure 14.20 shows how the memory values change after these changes. Observe
how num2 now contains the value of 100. The change in num2's value has no
impact on num1's value.

The value of p2's name is now George. The problem is that both p1 and p2
reference the same memory address. We have created an undesirable change for
p1 due to the change in p2. This type of problem, called aliasing, occurred
because two different objects referenced the exact same memory address.

Picture this. Imagine that by some computer error, two bank customers have the
same identical account numbers. Any deposit or withdrawal made by one
customer will automatically also alter the account balance of the other customer.




                                               Chapter XIV   Serious OOP   14.31
Figure 14.20

        p1                     p2                      num1
         @dff6ccd              @dff6ccd                15


                                                       num2
                                                       100
             dff6ccd                601bb1

         George                Tom




Aliasing

Aliasing occurs when two or more variables reference the
same memory location. Any change in the value of one
variable brings about a change in the value of the other
variable(s).




You should now have a better understanding how program Java1412.java created
such an unusual output. This is great, but it still begs the question why simple
data types and objects handle their memory differently. In this chapter you will
learn one reason, which is parameter passing. For many chapters, parameter
passing has been used with many different methods. The mechanics of parameter
passing has never been explained. It was simply looked upon as a convenient way
of passing information, which is processed by the method you called.

Program Java1414.java, in figure 14.21, uses a method, which does nothing
besides letting you look at the values of the parameters passed to the method.
Method parameterDemo uses three parameters: an int parameter, a Person
parameter and an int array. In the main method of the program the values of each
calling parameter is displayed before it arrives at the method. Once inside the
method, the values of the method parameters are also displayed.




14.32   Exposure Java, 2007 Edition   08-18-07
Figure 14.21
// Java1414.java
// This program demonstrates the difference between simple, primitive data and objects. Simple data passes a
// value to a method and objects pass a memory address reference to a method.

public class Java1414
{
    public static void main (String args[])
    {
         System.out.println("\nJava1414.java\n");
         Person p1 = new Person("Tom");
         Person p2 = new Person("Liz");
         int intList1[] = {1,2,3,4,5};
         int intList2[] = {5,4,3,2,1};
         System.out.println("\np1 value:      " + p1);
         System.out.println ("intList1 value: " + intList1);
         System.out.println("\np2 value:      " + p2);
         System.out.println ("intList2 value: " + intList2);
         System.out.println("\nCalling parameterDemo method");
         parameterDemo(7,p1,intList1);
         System.out.println("\nCalling parameterDemo method");
         parameterDemo(20,p2,intList2);
         System.out.println();
    }

    public static void parameterDemo(int years, Person p, int list[])
    {
        System.out.println("Parameter years value: " + years);
        System.out.println("Parameter p value:    " + p);
        System.out.println("Parameter list value: " + list);
    }
}


class Person
{
    private String name;

    public Person(String n)
    {
        name = n;
    }
}



                                                                             Java1414java Output

Java1414.java

p1 value:       Person@df6ccd
intList1 value: [I@601bb1

p2 value:       Person@ba34f2
intList2 value: [I@ea2dfe

Calling parameterDemo method
Parameter years value: 7
Parameter p value:      Person@df6ccd
Parameter list value:   [I@601bb1

Calling parameterDemo method
Parameter years value: 20
Parameter p value:      Person@ba34f2
Parameter list value:   [I@ea2dfe




                                                                   Chapter XIV    Serious OOP         14.33
The parameterDemo method is called twice with two different sets of values.
The integer calling parameters 7 and 20 display the exact same values inside the
method. Person objects p1 and p2 display memory addresses in the main
methods and the same memory addresses are shown by the p object inside the
parameterDemo method. Finally the int objects intList1 and intList2 display
memory addresses in the main method, and once again we observe the same
memory values by the list object inside the parameterDemo method.

So far this seems to be same song, different verse. By now you have seen and
accepted that simple data types store assigned values and objects store memory
addresses. Patience!! Something subtle is happening here. You should have
realized by this demonstration so far that no matter what kind of data type is
passed to a method, a copy is made of the calling parameter and assigned to the
receiving parameter in the method.

Imagine for a moment that all data types handle memory the same way. Objects
use no funky references to other memory locations, they store actual object
information. Now because objects are data structures, they have the capability to
store very large quantities of information. Just picture an array of one-million
integers. Such an array would occupy eight-million bytes of memory. Now
continue to imagine that this array is passed as a parameter to some method. With
the trusty copy method all one-million integers need to be copied. That is a time-
consuming amount of computer processing. Even worse, another eight-million
bytes of memory need to be used to store the copied array. The same exact array
is now stored twice in a hopelessly inefficient process.

Java avoids this double inefficiency of processing time and memory waste by
using memory references. The array information and other object information are
neatly stored in some memory location. Any method with the need to process any
object receives information where the object is located. It is not necessary to
make a copy of all the values in the object. Only a copy of the object's memory
location is copied and that information is sufficient to make the method
functional.

If all of this makes sense to you then you should realize a very important
consequence of passing parameters in this manner. The calling parameters of
simple data types are not altered by any action in a method. On the other hand,
can object values be changed? Program Java1415.java, in figure 14.22, looks at
that issue.




14.34   Exposure Java, 2007 Edition   08-18-07
Figure 14.22
// Java1415.java
// This program demonstrates what happens when simple data types and objects are passed to
// another method (qwerty) as parameters, and those parameters are altered in the method.
// In both cases, while the data is altered inside the qwerty method, the data remains
// unchanged when the qwerty method is finished.

public class Java1415
{
    public static void main (String args[])
    {
         System.out.println("\nJava1415.java\n");
         int intNum = 100;
         String myName = "Bob";

        System.out.println("main method values");
        System.out.println("intNum: " + intNum);
        System.out.println("myName: " + myName);

        qwerty(intNum,myName);

        System.out.println("\nmain method values");
        System.out.println("intNum: " + intNum);
        System.out.println("myName: " + myName);
        System.out.println();
    }

    public static void qwerty(int num, String name)
    {
        num += 100;
        name = "Joe";
        System.out.println("\nqwerty method values");
        System.out.println("num: " + num);
        System.out.println("name: " + name);
    }
}




Figure 14.22 Continued
                                                                         Java1415.java Output

Java1415.java

main method values
intNum: 100
myName: Bob

qwerty method values
num:   200
name: Joe

main method values
intNum: 100
myName: Bob




                                                             Chapter XIV       Serious OOP   14.35
The output shows that neither the simple data type, nor the object (remember...
Strings are objects) was altered by the qwerty method. When a parameter is
passed, a copy of the information is sent in the parameter to the method. In the
case of a simple data type, it is a copy of the simple data type value, like 23 for an
int, or 'A' for a char, or true for a boolean. Any changes performed by the
method are changes to a copy. The original is unaffected. In the case of an
object, it is a copy of the memory address of the object that is passed. As with the
simple data types, any changes to the object's memory address will have no affect
on the original memory address. So is it possible for a method to alter any values?
The answer is "yes", as long as it is the attributes of the object that are changed.
This is demonstrated in program Java1416.java, in figure 14.23.


Figure 14.23
// Java1416.java
// This program demonstrates that when an object is passed as a parameter to a method,
// any changes to the ATTRIBUTES of that object will remain when the method is finished.

public class Java1416
{
    public static void main (String args[])
    {
         System.out.println("\nJava1416.java\n");
         Person p = new Person("Bob",29);
         System.out.println("main method values");
         p.showData();
         qwerty(p);
         System.out.println("\nmain method values");
         p.showData();
         System.out.println();
    }

    public static void qwerty(Person p)
    {
        p.alterName("Joe");
        p.alterAge(37);
        System.out.println("\nqwerty method values");
        p.showData();
    }
}

class Person
{
    String name;
    int age;

    Person(String n, int a)             { name = n; age = a; }

    void alterName(String newName)      { name = newName; }

    void alterAge(int newAge)           { age = newAge; }

    void showData()
    {
        System.out.println("name: "+name);
        System.out.println("age: "+age);
    }
}




14.36      Exposure Java, 2007 Edition            08-18-07
Figure 14.23 Continued
                                              Java1416.java Output

Java1416.java

main method values
name: Bob
age: 29

qwerty method values
name: Joe
age: 37

main method values
name: Joe
age: 37




Java Parameters

Java passes information to a method with parameters.

A copy of the calling, actual parameter is assigned to the
receiving, formal parameter in the method.

In the case of a simple/primitive data type, a copy of the
variable’s value, like 23, ‘A’, or true, is sent by the
parameter. Any changes are changes to a copy, which
makes no changes to the original.

The same thing actually happens in the case of an object;
however, with an object the value is the memory address
of the object itself. If this is changed, it does not alter the
memory address of the original object.

The only way changes made in a method impact the
original calling object, is if changes are made to the
attributes of the object.

NOTE: Strings are objects, even though they tend to
behave like simple/primitive data types in some programs.
The true nature of Strings will be discussed in great detail
in Chapter 16.




                                     Chapter XIV   Serious OOP   14.37
14.11 Using the "this" Reference

There are times when identifiers can cause confusion. What happens if you create
a constructor and the parameter identifiers of the method are identical to the
attribute identifiers of the class? Does Java know how to handle such a situation?
Well Java has little problems with that scenario, but you may not like the result.
Program Java1417.java, in figure 14.24 creates the described scenario and check
what the output does. The values passed to the new object are not shown. What
is shown are a bunch of undesirable default values.


Figure 14.24
// Java1417.java
// This program intentionally uses identical parameter identifiers in the constructor method
// as the private attribute identifiers of the Car class. This has an undesirable result.


public class Java1417
{
    public static void main (String args[])
    {
         System.out.println("\nJava1417.java\n");
         Car ford = new Car("Explorer",2002,30000.0);
         ford.showData();
         System.out.println();
    }
}


class Car
{
    private String make;
    private int year;
    private double cost;

    public Car(String make, int year, double cost)
    {
        make = make;
        year = year;
        cost = cost;
    }

    public void showData()
    { System.out.println("make: " + make);
        System.out.println("year: " + year);
        System.out.println("cost: " + cost);
    }
}



                                                                                 Java1417java Output

Java1417.java

make:          null
year:          0
cost:          0.0




14.38      Exposure Java, 2007 Edition               08-18-07
Java has to make a decision. You come up with a clever method statement like
make = make; and what is Java to do? Now you have seen statements before
such as number = number + 100; and such a statement is no problem. The value
of number is replaced by a new value that is increased by 100. One thing is for
sure, you cannot have two identical identifiers in the same statement having two
different meanings. In the case of program Java1417.java, Java assumes that
make is the identifier of the local variable, and information is not passed properly.

There is a solution to this situation. Program Java1418.java, in figure 14.25,
solves the problem. Java has a special reference available that indicates the
current object. The reference has the clever name this and helps to straighten out
any Java confusion that may be caused. Now the statement this.make = make; is
no longer confusing - to Java - and gives the desired result. Java sees two
different identifiers in one statement. make is the parameter variable ready to
pass a value to the object. this.make is a reference to the current object and
specifically the make data attribute of the object.


Figure 14.25
// Java1418.java
// The problem of the previous program is solved by using the "this" reference
// to explicitly indicate the meaning of an identifier.

public class Java1418
{
    public static void main (String args[])
    {
         System.out.println("\nJava1418.java\n");
         Car ford = new Car("Explorer",2002,30000.0);
         ford.showData();
         System.out.println();
    }
}

class Car
{
    private String make;
    private int year;
    private double cost;

    public Car(String make, int year, double cost)
    {
        this.make = make;
        this.year = year;
        this.cost = cost;
    }

    public void showData()
    {
        System.out.println("make: " + make);
        System.out.println("year: " + year);
        System.out.println("cost: " + cost);
    }
}




                                                                 Chapter XIV     Serious OOP   14.39
Figure 14.25 Continued
                                                                           Java1418.java Output

Java1418.java

Make:          Explorer
Year:          2002
Cost:          30000.0




One quickie program, with an even quicker explanation, of the this reference
probably does not turn on that many lights in the brain department. You will see
three additional programs that use this, starting with Java1419.java, in figure
14.26, which displays the value of the new Widget object as well as the value of
the this reference.


Figure 14.26
// Java1419.java
// This program demonstrates that <this> stores the same reference value
// as its corresponding object, which in this case is w.


public class Java1419
{
    public static void main (String args[])
    {
         System.out.println("\nJava1419.java\n");
         Widget w = new Widget(100);
         System.out.println("There are " + w.getWidgets() + " widgets");
         System.out.println();
         System.out.println("w = " + w);
         System.out.println("this = " + w.getThis());
         System.out.println();
    }


}


class Widget
{
    private int numWidgets;

    public Widget(int nw)
    {
        numWidgets = nw;
    }

    public int getWidgets()
    {
        return numWidgets;
    }

    public Widget getThis()
    {
        return this;
    }
}




14.40      Exposure Java, 2007 Edition             08-18-07
Figure 14.26 Continued
                                                                           Java1419.java Output


Java1419.java

There are 100 widgets

w =    Widget@82ba41
this = Widget@82ba41




The output of Java1419.java proves that the memory reference of the w object is
identical to the memory reference returned by the getThis method. So far only a
single this is used. Program Java1420.java, in figure 14.27, adds the Vidget
class. Now there are two classes with two different objects and there are two calls
to two different getThis methods.


Figure 14.27
// Java1420.java
// This program uses two different class and each class has a <getThis> method.
// Note that methods <getThis> return the same value as their object w or v.


public class Java1420
{
    public static void main (String args[])
    {
         System.out.println("\nJava1420.java\n");
         Widget w = new Widget(100);
         Vidget v = new Vidget(200);
         System.out.println();
         System.out.println("w = " + w);
         System.out.println("this = " + w.getThis());
         System.out.println();
         System.out.println("v = " + v);
         System.out.println("this = " + v.getThis());
         System.out.println();
    }


}


class Widget
{
    private int numWidgets;

    public Widget(int nw)
    {
        numWidgets = nw;
    }

    public Widget getThis()
    {
        return this;
    }
}




                                                               Chapter XIV        Serious OOP   14.41
class Vidget
{
    private int numVidgets;

    public Vidget(int nv)
    {
        numVidgets = nv;
    }

    public Vidget getThis()
    {
        return this;
    }
}



Figure 14.27 Continued
                                                         Java1420.java Output



Java1420.java


w =    Widget@923e30
this = Widget@923e30

v =    Vidget@130c19b
this = Vidget@130c19b




Does the output make sense? You should expect two different memory addresses
for two different objects. Do you realize that there is not just a single this
reference floating around with a constant value? The this reference stores the
memory address of its own object. Perhaps you find this strange. How can the
this reference have multiple values? It really is not strange at all. Imagine that
you stand inside a room and you state this room is too small for my presentation.
You search around the building and now you arrive at a different room where you
state this room is the right size. I will do my presentation here.

Now you mentioned this room twice. The reality is that you were talking about
two different rooms, just like the java program is talking about two different
objects. The value of the this reference depends on the context of the object in
the program. Calling getThis with a w object and then a v object is the same
concept as walking to a different room. The this reference has the same name, but
it has a different memory value.

Now is there some purpose for this (pun intended)? Program Java1421.java, in
figure 14.28, shows a non-functional game. Keep in mind that actual games
involve complex programming that will totally hide the point of this this business.
In the next program example you see a Game object instantiated in the main
method, followed by a call to start the game. This is proper Object Oriented



14.42     Exposure Java, 2007 Edition   08-18-07
Design, where the main method is kept to a minimum of statements. In a well
designed program, objects communicate with each other. The Game constructor
creates three Player objects and then prepares to let the Strategy object take over.
Now the Strategy object needs all the Game information, which is achieved by
passing the entire Game object to the Strategy constructor. Now we have a slight
problem. We happen to be inside the Game class. How do we pass the proper
information? You guessed it, we use the this reference as a parameter to another
method.


Figure 14.28
// Java1421.java
// This demonstrates how to pass the entire object information to another method.


public class Java1421
{
    public static void main (String args[])
    {
         System.out.println("\nJava1421.java\n");
         Game game = new Game();
         System.out.println("game object reference is " + game);
         game.startGame();
         System.out.println();
    }


}


class Game
{
    Player p1;
    Player p2;
    Player p3;
    Strategy s;

    public Game()
    {
        System.out.println("Inside the Game constructor");
        p1 = new Player("Tom");
        p2 = new Player("Sue");
        p3 = new Player("Kim");
    }

    public void startGame()
    {
        System.out.println("Inside method startGame");
        s = new Strategy(this);
    }

}


class Player
{
    private String name;

    public Player(String n)
    {
        System.out.println("Inside the Player Constructor");
        name = n;
    }
}



                                                                   Chapter XIV      Serious OOP   14.43
class Strategy
{
    public Strategy(Game obj)
    {
        System.out.println("Inside Strategy Constructor");
        System.out.println("Using the Game object reference " + obj);
    }
}



Figure 14.28
                                                                        Java1421.java Output


Java1421.java

Inside the Game constructor
Inside the Player Constructor
Inside the Player Constructor
Inside the Player Constructor
game object reference is Game@923e30
Inside method startGame
Inside Strategy Constructor
Using the Game object reference Game@923e30




Consider the rooms-analogy one more time to help clarify the information
passing. First, you are in the office of an architect and you say I want you to build
the new school with a presentation hall that is identical to the Sophomore
Presentation Hall at John Paul II High School. In this example, I am using a
named object. It somewhat like saying makeRoom(JPIIHS_Hall);

Now suppose you are talking to the architect and you are standing inside the
Sophomore Presentation Hall of john Paul II High School. Now you say I want
you to build the new school with a presentation hall like this hall. Now I am not
using a named object.       I am inside the object, which is like saying
makeRoom(This_Hall);




14.44     Exposure Java, 2007 Edition             08-18-07
14.12 Nesting Classes with Composition

Surely you must be getting excited about all this OOP business. Section after
section is more stimulating than the previous section. You will need to apologize
to your other teachers because it is not possible to put this chapter down. You
should note that the majority of the topics in this chapter were already introduced,
but this re-introduction is designed to clear up lingering confusion. Additionally,
details are explained that would have been too complex earlier in the course.

You have seen a bunch of classes, mostly a Person class that slowly improved
and must wait for some future chapter to reach its natural conclusion. You have
also seen some other examples and in each case there has been a bunch of data
and some methods that act upon the data. Congratulations, because you have just
described encapsulation, and well ... that topic is getting old. Have you noticed
anything about all the data types of the class attributes that we have used? All the
data are simple types. Simple types are just a bunch of integers, characters and
doubles and some occasional Strings thrown in. Well what if you wanted to
create a class that contains some other class as part of its private attributes? That
can happen, and it is quite normal in OOP.

First, we must set the stage. Program Java1422.java, in figure 14.29, introduces
the Engine class. It is a simple class that will be used in the next program. Right
now your mission is to understand the Engine class. The Engine class stores the
number of cylinders, the size of the engine in liters and the engine power in
horsePower. The class has a parameter constructor to assign private attribute
values and three get-methods to access data values.




Figure 14.29
// Java1422.java
// This program introduces the Engine class, which will be used in the next
// program to demonstrate composition.

public class Java1422
{
    public static void main(String args[])
    {
         System.out.println("\nJava1422.java\n");
         Engine iForce = new Engine(8,4.7,265);
         System.out.println("Cylinders:    " + iForce.getCylinders());
         System.out.println("Size:         " + iForce.getSize());
         System.out.println("HorsePower: " + iForce.getHP());
         System.out.println();
    }
}




                                                                   Chapter XIV   Serious OOP   14.45
class Engine
{
    private int cylinders;       // number of cylinders in the engine
    private double liters;       // displacement of the engine in liters
    private int horsePower; // horsepower of the engine

    public Engine(int cyl, double size, int hp)
    {
        cylinders = cyl;
        liters = size;
        horsePower = hp;
    }

    public int getCylinders()     { return cylinders; }
    public double getSize()       { return liters; }
    public int getHP()                 { return horsePower; }
}



                                                                           Java1422.java Output
Java1422.java

Cylinders: 8
Size:       4.7
HorsePower: 265




The industrial world uses an assembly line to create cars. Now does it make sense
that a Car assembly line uses another assembly line that provides an engine? In
other words, it is quite reasonable that our clever Engine class is used as a
member of another Car class. Perhaps that is reasonable enough, but do you
know how to handle the syntax of such a "nested object" situation? OOP has a
name for this situation: it is called Composition, which happens when one class
is composed of elements that include another class. Program Java1423.java, in
figure 14.30, shows both the Engine class and the Car class. What is of
particular interest is the Car constructor. This constructor needs to pass
information to the Car object's private attributes. So far that is not too tricky.
However, before a Car object can be created there first must be an Engine object.
Notice how inside the Car constructor an Engine object is instantiated.


Figure 14.30
// Java1423.java
// This program demonstrates "composition", which uses multiple classes in
// such a way that an object of one class become a data member of another class.

public class Java1423
{
    public static void main(String args[])
    {
         System.out.println("\nJava1423.java\n");
         Car toyota = new Car("Tundra",4,"Red",8,4.7,265);
         toyota.displayCar();
         System.out.println();
    }
}




14.46      Exposure Java, 2007 Edition              08-18-07
class Engine
{
    private int cylinders;  // number of cylinders in the engine
    private double liters;  // displacement of the engine in liters
    private int horsePower; // horsepower of the engine

    public Engine(int cyl, double size, int hp)
    {
        cylinders = cyl;
        liters = size;
        horsePower = hp;
        System.out.println("Engine Object Finished\n");
    }

    public int getCylinders() { return cylinders; }
    public double getSize()        { return liters; }
    public int getHP()             { return horsePower; }
}


class Car
{
    private String carMake;
    private int carDoors;
    private String carColour;
    private Engine carEngine;

    public Car(String cm, int cd, String cc, int cyl, double size, int hp)
    {
        carMake = cm;
        carDoors = cd;
        carColour = cc;
        carEngine = new Engine(cyl,size,hp);
        System.out.println("Car Object Finished\n");
    }

    public void displayCar()
    {
        System.out.println("carMake:   " + carMake);
        System.out.println("carDoors: " + carDoors);
        System.out.println("carColour: " + carColour);
        System.out.println("cylinders:  " + carEngine.getCylinders());
        System.out.println("size:       " + carEngine.getSize());
        System.out.println("horsePower: " + carEngine.getHP());
    }
}



Figure 14.30 Continued
                                                                              Java1423.java Output

Java1423.java

Engine Object Finished
Car Object Finished
carMake:     Tundra
carDoors:    4
carColour:   Red
cylinders:   8
size:        4.7
horsePower: 265




                                                                     Chapter XIV   Serious OOP   14.47
14.13 Static Attributes and Methods

The Java reserved word static has appeared since the very first introduction of a
Java program. Back in those early days you were told to use a program template
and not be concerned about all the details yet. Several chapters later you were
introduced to class methods, and it turned out that all these methods were static.
We now return to this topic and examine the peculiarities of this static declaration
business in greater detail.

A class is a template for the creation of multiple objects. Why do we need
multiple objects? We use multiple objects to store data for multiple situations.
We may have a Student class that is used to record grades, enter attendance,
determine GPAs, etc. Each object of the Student class represents the information
for one student. The methods used with each object are the same. The difference
is that each object stores its own data. This brings up a question. What happens if
you create a class and that class has no need to store data? Java has such a class,
which it is the Math class. This is a class with many methods, called functions in
math, which return values based on provided parameters. You do not really need
to know how the Math class is implemented. You use the class, but the source
code is hidden.

Now we can simulate a simple mathematical class, called Calc. The Calc class
simulates a four-function calculator. There are four methods for each one of the
basic four arithmetic operations. There are no data attributes to store data.
Program Java1424.java, in figure 14.31, tests the Calc class. The class
declaration looks pretty normal, but note that each method includes the static
keyword in the method heading. Class Java1424 uses the Calc class and you do
not see any instantiation of an object.



Figure 14.31
// Java1424.java
// This program demonstrates the use of static "class" methods that do not require
// the creation of an object.


public class Java1424
{
    public static void main(String[] args)
    {
         System.out.println("\nJava1424.java\n");
         System.out.println("100 + 33 = " + Calc.add(100,33));
         System.out.println("100 - 33 = " + Calc.sub(100,33));
         System.out.println("100 * 33 = " + Calc.mul(100,33));
         System.out.println("100 / 33 = " + Calc.div(100,33));
         System.out.println();
    }
}




14.48     Exposure Java, 2007 Edition             08-18-07
class Calc
{
    public static double add(double a, double b)
    {
        return a + b;
    }
    public static double sub(double a, double b)
    {
        return a - b;
    }
    public static double mul(double a, double b)
    {
        return a * b;
    }
    public static double div(double a, double b)
    {
        return a / b;
    }
}



                                                            Java1424.java Output

Java1424.java

100   +   33   =   133.0
100   -   33   =   67.0
100   *   33   =   3300.0
100   /   33   =   3.0303030303030303




This use of using static is a review, but does it make sense? Why would there be
a need to construct multiple objects of the Calc class to use any one of the four
arithmetic functions? The whole point of encapsulation is that you have this set
of methods, which process the data of its own object. You see the same methods
processing different data for different objects. But in the case of our Calc class
the data, which is processed, is not stored by an object at all. The data is passed
by parameter to one of the four Calc methods.

In other words, our life has become a little simpler. We have access to the
functionality of the Calc class without spending extra program statements that
instantiate a bunch of Calc objects. There are two requirements to use this
convenience. First, you need to declare the methods as static and second, you use
the class identifier when you call the any of its methods.

Do you have to use the class identifier? Is it possible to treat the Calc class like
other classes that are used to instantiate objects. Well let us try it out and see what
happens. In program Java1425.java, shown in figure 14.32, the program is
almost identical to the previous example. The only difference is that this time a
Calc object is constructed and then used to call each one of the four Calc
methods.




                                                   Chapter XIV   Serious OOP     14.49
Figure 14.32
// Java1425.java
// This program uses the same Calc class as the previous program. This time an object
// of the Calc class is constructed. This is possible, but not necessary.

public class Java1425
{
    public static void main(String[] args)
    {
         System.out.println("\nJava1425.java\n");
         Calc c = new Calc();
         System.out.println("100 + 33 = " + c.add(100,33));
         System.out.println("100 - 33 = " + c.sub(100,33));
         System.out.println("100 * 33 = " + c.mul(100,33));
         System.out.println("100 / 33 = " + c.div(100,33));
         System.out.println();
    }
}


class Calc
{
    public static double add(double a, double b)
    {
        return a + b;
    }
    public static double sub(double a, double b)
    {
        return a - b;
    }
    public static double mul(double a, double b)
    {
        return a * b;
    }
    public static double div(double a, double b)
    {
        return a / b;
    }
}



                                                                           Java1425.java Output

Java1425.java

100   +   33   =   133.0
100   -   33   =   67.0
100   *   33   =   3300.0
100   /   33   =   3.0303030303030303




The output is identical to the previous program. Apparently, it does not make any
difference whether you use the class identifier or the object identifier. It true that
you can do this, but even though the example of Java1425.java is allowed, this
approach is not suggested. If you are using static methods make sure to use the
class identifier.




14.50      Exposure Java, 2007 Edition             08-18-07
Class Methods

It is possible to access methods directly without first creating
an object. Methods that are accessed in this manner are called
Class Methods.
Class methods need to be declared with the static keyword
used in the heading like:
      public static double add(double a, double b)
      {
         return a + b;
      }

Accessing a class method is done with the class identifier,
followed by the method identifier, like:
      System.out.println(Calc.add(X,Y));


It is possible to access static methods with object identifiers.
This is considered poor styling and should be avoided.




You could be under the impression that a class with static methods has no
attributes. That is not exactly true. Recall that the Math class has attributes PI
and E. There are other applications for static methods, besides utilities, like
calculating, centering, etc., and you will be pleased to know that you can also have
static attributes. As a matter of fact it is possible to mix static and non-static
members in the same class declaration. This probably all sounds very confusing,
so let's try to create a practical scenario.

In a non-static OOP world an object is instantiated and data is initialized and
processed. If multiple objects of the same class are constructed than each object
stores its own set of data until the object is no longer in scope. In this type of
program the objects do not share any information. The only thing they share is the
fact that all objects are created from the same class template.

Now suppose that you have a class that plays some type of game. The nature of
the game is not important. All that matters is that each person who plays the game
generates a score. Now score is a private attribute of the Game class and when
somebody finishes the game, the value of score is lost when the object is no
longer in scope. Did you do well playing the game? Such a question can only be


                                                Chapter XIV    Serious OOP    14.51
answered if your score can be compared to some highScore. highScore is also a
private attribute of the Game class, but how is comparison possible with a
previous object's score, when these scores disappear along with the object.

The secret is to declare highScore static. When an object of the Game class is
finished, the value of highScore does not disappear and can still be accessed by a
later object. If the later object has a better score, the highScore value can be
updated. It is important not to confuse static with final. It is possible to change
the values of static variables. The key difference is that static variables are class
variables and do not leave scope.

Program Java1426.java, in figure 14.33, mixes static and non-static class
members. The player's name and the current player’s score are non-static and
need to be stored as part of the current object. Only highScore is declared as a
static attribute of the Game class. Additionally, you will find that the getHS and
the setHS methods are both static methods. This program example does store
information, and you do need to instantiate one object for each Game player, but
at the same time you want to keep some information available to all objects. That
is why the class has a mixed set of static and non-static members.


Figure 14.33
// Java1426.java
// This program is an example of multiple objects using the same static class attribute.
// Note how the use of object identifiers with object methods and the class identifiers with class methods.

public class Java1426
{
    public static void main(String[] args)
    {
         System.out.println("\nJava1426.java\n");
         int newScore;
         Game.setHS(1000);
         System.out.println("Starting with default high score of 1000\n");
         Game p1 = new Game("Tom");
         System.out.println(p1.getName() + "'s score is " + p1.getScore() +
              " compared to " + Game.getHS() + " high score\n");
         newScore = p1.getScore();
         if (newScore > Game.getHS())
              Game.setHS(newScore);
         Game p2 = new Game("Sue");
         System.out.println(p2.getName() + "'s score is " + p2.getScore() +
              " compared to " + Game.getHS() + " high score\n");
         newScore = p2.getScore();
         if (newScore > Game.getHS())
              Game.setHS(newScore);
         Game p3 = new Game("Lois");
         System.out.println(p3.getName() + "'s score is " + p3.getScore() +
              " compared to " + Game.getHS() + " high score\n");
         newScore = p3.getScore();
         if (newScore > Game.getHS())
              Game.setHS(newScore);
         System.out.println("Highest score is " + Game.getHS());
         System.out.println();
    }
}




14.52      Exposure Java, 2007 Edition             08-18-07
class Game
{
    private static int highScore;   // highest score of any game played
    private int score;              // current object score
    private String player;          // name of the current player

    public Game(String Name)
    {
        player = Name;
        playGame();
    }

    public String getName()         { return player; }
    public static int getHS()       { return highScore; }
    public int getScore()           { return score; }

    public void playGame()
    {
        score = (int) (Math.random() * 10000);
    }

    public static void setHS(int newScore)
    {
        highScore = newScore;
    }

}




Figure 14.33 Continued
                                                                          Java1426.java Output

Java1426.java

Starting with default high score of 1000

Tom's score is 6724 compared to 1000 high score

Sue's score is 3396 compared to 6724 high score

Lois's score is 6132 compared to 6724 high score

Highest score is 6724




This static section will finish with one more example. Program Java1427.java,
in figure 14.34, presents a program to manage school finances. The program
keeps track of individual budgets for three different departments and it also keeps
track of the overall school's financial balance. Separate objects are created for
each department in the school, and each department object controls its own
allocated portion of the school budget. Purchases made by one department do not
alter the balance of any other department, but it does impact the school balance.
For this reason the school's balance is made static.




                                                               Chapter XIV   Serious OOP   14.53
Figure 14.34
// Java1427.java
// This program uses static attributes and static methods to store school
// budget information and object attributes and object methods to store department information.

public class Java1427
{
    public static void main(String[] args)
    {
         System.out.println("\nJava1427.java\n");
         Budget.setSchoolBalance(100000);
         System.out.println("Starting school balance: " + Budget.getSchoolBalance() + "\n");
         Budget b1 = new Budget("English",20000);
         Budget b2 = new Budget("Math",15000);
         Budget b3 = new Budget("Comp Science",6000);
         System.out.println();
         b1.setDeptBalance(-5000);
         System.out.println("Deduct 5000 from English");
         System.out.println(b1.getDeptBalance() + " left in " + b1.getDeptName());
         System.out.println(Budget.getSchoolBalance() + " left in school budget\n");
         System.out.println("Deduct 8000 from Math");
         b2.setDeptBalance(-8000);
         System.out.println(b2.getDeptBalance() + " left in " + b2.getDeptName());
         System.out.println(Budget.getSchoolBalance() + " left in school budget\n");
         System.out.println("Deduct 9000 from Comp Science");
         b3.setDeptBalance(-9000);
         System.out.println(b3.getDeptBalance() + " left in " + b3.getDeptName());
         System.out.println(Budget.getSchoolBalance() + " left in school budget\n");
    }
}


class Budget
{
    private static int schoolBalance;    // money left in school budget
    private int deptBalance;             // money left in department budget
    private String deptName;             // stored department name

    public Budget (String dn,int db)
    {
        deptBalance = db;
        deptName = dn;
        System.out.println("Constructing " + dn + " object with " + db);
    }
    public static void setSchoolBalance(int amount)
    {
        schoolBalance += amount;
    }
    public static int getSchoolBalance()
    {
        return schoolBalance;
    }
    public void setDeptBalance(int amount)
    {
        deptBalance += amount;
        setSchoolBalance(amount);
    }
    public String getDeptName()
    {
        return deptName;
    }
    public int getDeptBalance()
    {
        return deptBalance;
    }
}




14.54      Exposure Java, 2007 Edition             08-18-07
Figure 14.34 Continued
                                               Java1427.java Output

Java1427.java

Starting school balance: 100000

Constructing English object with 20000
Constructing Math object with 15000
Constructing Comp Science object with 6000

Deduct 5000 from English
15000 left in English
95000 left in school budget

Deduct 8000 from Math
7000 left in Math
87000 left in school budget

Deduct 9000 from Comp Science
-3000 left in Comp Science
78000 left in school budget




Static Methods and Static Attributes

Static methods and static attributes can be accessed for the
entire duration of a program.

Static variables (attributes) can be accessed by static methods
and object methods.

Instance variables (attributes) can only be accessed by object
methods.

Static attributes can be accessed with object identifiers and
class identifiers.




                                      Chapter XIV   Serious OOP   14.55
14.14 The FishGfx class

For the final program you will be using a FishGfx class. In this case the source
code of the FishGfx class will not be shown. You are provided with the compiled
bytecode file that is necessary to execute program Java1428.java, shown in figure
14.35. This same FishGfx class will also be used for the lab assignments at the
conclusion of this chapter.



Figure 14.35
// Java1428.java
// A series of fishes is drawn on a two-dimensional fishtank grid.
// The file FishGfx.class must be in the same folder as this file for the program to compile.
// Students can use the methods of the FishGfx class, even if they do not understand how they work.
// This program needs top be viewed in 1024 X 768 resolution.


import java.awt.*;

public class Java1428 extends java.applet.Applet
{
  public void paint(Graphics g)
  {
     FishGfx f = new FishGfx(g,20,20,4000);
     int count = 1;
     int clr = 1;
     for (int col = 0; col < 20; col++)
     {
        f.drawFish(g,col,col,clr,count);
        count++;
        clr++;
        if (clr > 9)
            clr = 1;

            f.drawFish(g,col,19-col,clr,count);
            count++;
            clr++;
            if (clr > 9)
                clr = 1;
        }

        for (int col = 0; col < 20; col++)
        {
           f.eraseFish(g,col,col);
           f.eraseFish(g,col,19-col);
        }
    }
}




14.56          Exposure Java, 2007 Edition         08-18-07
Figure 14.35 Continued




Since you are not provided with the actual FishGfx class, you need to know the
interface to the class. This involves knowledge of how to use this class. How
objects are constructed, what public methods are available and what type of
parameters do they require?

In general, the FishGfx class assists in manipulating graphics fishes on a
simulated fish tank. The fish tank is divided up into cells, such that each cell
represents the space required for one fish. An object of the FishGfx class
includes two parameters to indicate the number of rows and columns of the grid.
Basically, the tank looks like a graphics matrix that displays fish in the cells of the
matrix.

Methods of the FishGfx class include three private methods delay, getColor and
drawGrid. You cannot access these methods. They are used by other, public
methods. The constructor calls the drawGrid method. Your biggest concern is
with the drawFish and the eraseFish methods. Both methods use the private
delay method to slow down the graphic display. Both methods indicate the
coordinate location where a fish will be drawn or erased. Keep in mind that the
coordinates that you provide are not absolute pixel coordinates, but fish tank grid


                                                  Chapter XIV    Serious OOP     14.57
locations indicated by row and column location. The sample program will help to
demonstrate how to use objects of the FishGfx class.

Figure 14.36 is an abridged version of the FishGfx class. Only the method
headings are provided to learn the interface information that is required to use the
class properly. The drawFish method also has the capability to draw a fish with a
color constant. The private getColor method converts the integer parameter to a
Color class constant. The meaning of the numbers and color constants are shown
below. Additionally, drawFish can also draw a number (specifically an int) on
the fish. You will see in the program example, and your lab assignment, these
numbers help to identify which fish is which.


Figure 14.36
// FishGfx.java
// This is a partial source code file of the FishGfx class.
// Only the available method headings are shown. All implementations are hidden.

import java.awt.*;

class FishGfx
{
  private void delay(double n)
  // This method delays program execution where N is roughly the number of mili-seconds
  // of the delay. This method is called after DrawFish and EraseFish.
  // The only purpose of this method is to view the fish as they are drawn and erased.

 private Color getColor(int clr)
 // returns the following colors for integer parameter clr:
 // 1 red;
 // 2 green;
 // 3 blue;
 // 4 orange;
 // 5 cyan;
 // 6 magenta;
 // 7 yellow;
 // 8 pink;
 // 9 black;

 private void drawGrid(Graphics g, int l, int w)
 // draws a two-dimensional grid with l x w (Length x Width) fish locations

 public FishGfx(Graphics g, int rows, int cols, double td)
 // constructs a fishgfx object with specified dimensions and time delay (td)

 public void drawFish(Graphics g, int row, int col, int clr, int num)
 // draws a fish at the specified [row][col] grid location with color (clr) and a number(num)
 // to identify the fish

 public void eraseFish(Graphics g, int row, int col)
 // erases a fish at the specified row X col grid location
 // an intentional time delay is called at the conclusion




14.58     Exposure Java, 2007 Edition         08-18-07
So why a FishGfx class? Aside from the fact that many students find graphics
more interesting that plain text, this class also review important OOP concepts, as
well as providing an opportunity to review 2-Dimensional Array and Control
Structures. The FishGfx class is a fairly complicated class. However, it will not
be that difficult to comprehend the implementation of the class, but the truth is
that implementation understanding is neither necessary nor desired to create
programs with this class. This is part of a concept called Information Hiding
which will be explained in detail in the next chapter.

Do keep in mind that this program is written to be an applet. After you compile
the Java1428 class, you will need to use appletviewer to execute the
Java1428.html file along with the FishGfx class and view the output.




14.15 Summary

Program development requires that large programs are divided into smaller
program modules to be manageable. This is the principle of divide and conquer.

Structured programming is an organized style of programming that places
emphasis on modular programming, which aids testing, debugging and modifying.

In structured programming, modules are procedures and functions that process
external data passed by parameters.

Object Oriented Programming is a style of programming that incorporates
program development in a language with the following three OOP traits:
    Encapsulation
    Polymorphism
    Inheritance

Encapsulation is the process of placing a data structure’s data (attributes) with
the methods (actions) that act upon the data inside the same module, called a class
in Java.

Inheritance is the process of using features (both attributes and actions) from an
established higher class. The higher class is called the superclass. The lower
class is called the subclass.


                                                Chapter XIV   Serious OOP    14.59
Polymorphism allows a single accessing feature, such as an operator, method or
class identifier, to have many forms.

A class is a user-defined data type, which encapsulates both data and the methods,
which act upon the data.

An object is one instance of a class. A class is a type and an object is a variable.
Cat is a class and Fluffy is an object or one instance of the Cat class.

Objects can be discussed in a general sense, such as in Object Oriented
Programming. This causes confusion between Object, the concept and object, the
instance of a class. There is a tendency to use instance when referring to one
variable example of a class.

The data components of a class are the class attributes and they are also called
instance variables. Instance variables should only be accessed by methods of the
same class.

Methods are action modules, which process data. In other languages such
modules may be called subroutines, procedures and functions. In Java the
modules are called methods. They are declared inside a class module and process
the instance variables.

Instantiation is the moment or instance that memory is allocated for a specific
object of a class. Statements like the construction of an object, the definition of
an object, the creation of an object all have the same meaning as the instantiation
of an object. In most cases a class declaration is located outside any other class
declaration. It is possible to declare one class inside another class (inner class),
which will be explained later.

An object is created with the new operator. The creation of a new object is
called:
   instantiation of an object
   construction of an object

The special method that is called during the instantiation of a new object is called
a constructor.

A constructor is a method with the same identifier as the class. Constructors are
neither void nor return methods. A constructor is called during the instantiation
of an object. Constructors without parameters are default constructors.

The principle of encapsulation requires that object data are only accessed by
methods of the same object.



14.60   Exposure Java, 2007 Edition   08-18-07
Private class members of some object X can only be accessed by methods of the
same X object.

Public class members of some object X can be accessed by any client of object X.

Data attributes of a class should be declared private. Methods of a class are
usually declared public, but there are special "helper" methods that may also be
declared private.

Java programs should be divided into separate files. The normal convention is to
create one file for each class declaration. Place all class files of the same program
in the same directory.

A copy constructor is a constructor that instantiates a new object as a copy of an
existing object. A copy constructor uses a single parameter, which is an object of
the same class as the copy constructor.

Java passes all parameter information to a method by making a copy of the
passing parameter. This means that changes in the method's receiving, formal
parameter cannot change the literal value of the calling, actual parameter.
However, if objects are passed as a parameter than any changes to the object
attributes of the formal parameter will alter the attributes of the actual parameter.

It is possible to access methods directly without first creating an object. Methods
that are accessed in this manner are called Class Methods or Static Methods.

Class methods need to be declared with the static keyword used in the heading
like:
      public static double Add(double A, double B)
      {
        return A + B;
      }

Accessing a class method is done with the class identifier, followed by the method
identifier, like:
      System.out.println(Calc.Add(X,Y));



Static methods and static attributes can be accessed for the entire duration of a
program.

Static variables (attributes) can be accessed by static methods and object methods.

Instance variables (attributes) can only be accessed by object methods.

Static attributes can be accessed with object identifiers and class identifiers.


                                                     Chapter XIV   Serious OOP     14.61
14.62   Exposure Java, 2007 Edition   08-18-07

								
To top