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    Information Hiding

   14.14    Static Attributes and Methods

   14.15    Summary


14.1  Introduction

 

 

What kind of a chapter title is Serious OOP I ?  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, that 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.

 

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 and Object Methods.

 

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 I, 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.  You will be pleased to know that this chapter has Roman Numeral I, so you can expect this serious OOP stuff to continue in some later chapter.

 

 

 

 

 

 

 

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 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.

 

 

 

 

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. 

 

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.

 

 

 

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 and functions.  In Java the modules are called methods.  They are declared inside a class module and process the instance variables.

 

 

 

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 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

 

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 had no process capabilities.  It only contained attributes.  The program output consisted of output generated by the main method of the Java1401 class.  Nothing was contributed by Person01.  A p object was in fact instantiated and that was 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.

 

 

 

 

 

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, nor is it 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 new object with some value.  The general purpose of a constructor is to make an object ready to be used during program execution.  Such a task may require considerably more than assigning initial values.  You may remember the example of the CardDeck class, which includes shuffling the cards when a new CardDeck object is 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 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;

      }

   

}

 

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 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;