Object-Oriented Programming in Java
As we said at the beginning of this chapter, Java is an object-oriented language. When you use a programming language that is not object oriented, you must express the solution to every problem essentially in terms of numbers and characters - the basic kinds of data that you can manipulate in the language. In an object-oriented language like Java, things are different. Of course, you still have numbers and characters to work with - these are referred to as the basic data types - but you can define other kinds of entities that are relevant to your particular problem. You solve your problem in terms of the entities or objects that occur in the context of the problem. This not only affects how a program is structured, but also the terms in which the solution to your problem is expressed. If your problem concerns baseball players, your Java program is likely to have BaseballPlayer objects in it; if you are producing a program dealing with fruit production in California, it may well have objects that are Oranges in it. Apart from seeming to be inherently sensible, object-oriented programs are usually easier to understand.

In Java almost everything is an object. If you haven't delved into object-oriented programming before, or maybe because you have, you may feel this is a bit daunting. But fear not. Objects in Java are particularly easy. So easy, in fact, that we are going to start out by understanding some of the ideas behind Java objects right now. In that way you will be on the right track from the outset.

This doesn't mean we are going to jump in with all the precise nitty-gritty of Java that you need for describing and using objects. We are just going to get the concepts straight at this point. We will do this by taking a stroll through the basics using the odd bit of Java code where it helps the ideas along. All the code that we use here will be fully explained in later chapters. Concentrate on understanding the notion of objects first. Then we can ease into the specific practical details as we go along.

So What Are Objects?
Anything can be thought of as an object. Objects are all around you. You can consider Tree to be a particular class of objects: trees in general; although it is a rather abstract class as you would be hard pushed to find an actual occurrence of a totally generic tree. Hence the Oak tree in my yard which I call myOak, the Ash tree in your yard which you call thatDarnedTree, and a generalSherman, the well-known redwood, are actual instances of specific types of tree, subclasses of Tree that in this case happen to be Oak, Ash, and Redwood. Note how we drop into the jargon here - class is a term that describes a specification for a collection of objects with common properties.

A class is a specification, or template - expressed as a piece of program code - which defines what goes to make up a particular sort of object. A subclass is a class that inherits all the properties of the parent class, but that also includes extra specialization. Of course, you will define a class specification to fit what you want to do. There are no absolutes here. For my trivial problem, the specification of a Tree class might just consist of its species and its height. If you are an arboriculturalist, then your problem with trees may require a much more complex class, or more likely a set of classes, that involve a mass of arboreal characteristics.

Every object that your program will use will have a corresponding class definition somewhere for objects of that type. This is true in Java as well as in other object-oriented languages. The basic idea of a class in programming parallels that of classifying things in the real world. It is a convenient and well-defined way to group things together.


An instance of a class is a technical term for an existing object of that class. Ash is a specification for a type of object and yourAsh is an object constructed to that specification, so yourAsh would be an instance of the class Ash. Once you have a class defined, then you can come up with objects, or instances of that class. This raises the question of what differentiates an object of a given class, an Ash class object say, from a Redwood object. In other words, what sort of information defines a class?

What Defines a Class of Objects?
You may have already guessed the answer. A class definition lists all the parameters that you need to define an object of that particular class, at least, so far as your needs go. Someone else might choose a larger or smaller set of parameters to define the same sort of object - it all depends on what you want to do with the class. You will decide what aspects of the objects you need to include to define that particular class of object, and you will choose them depending on the kinds of problems that you want to address using the objects of the class. Let's think about a specific class of objects.

For a class Hat for example, you might use just two parameters in the definition. You could include the type of hat as a string of characters such as "Fedora" or "Baseball cap", and its size as a numeric value. These parameters that define an object of a class are referred to as instance variables or attributes of a class, or class fields. The instance variables can be basic types of data such as numbers, but they could also be other class objects. For example, the name of a Hat object could be of type String - the class String defines objects that are strings of characters.

Of course there are lots of other things you could include to define a Hat if you wanted to, color for instance, which might be another string of characters such as "Blue". To specify a class you just decide what set of attributes suit your needs, and those are what you use. This is called data abstraction in the parlance of the object-oriented aficionado, because you just abstract the attributes you want to use from the myriad possibilities for a typical object.

In Java the definition of the class Hat would look something like:

class Hat {
// Stuff defining the class in detail goes here.
// This could specify the name of the hat, the size,
// maybe the color, and whatever else you felt was necessary.
}

The name of the class follows the word class, and the details of the definition appear between the curly braces.

Important Because the word class has this special role in Java it is called a keyword, and it is reserved for use only in this context. There are lots of other keywords in Java that you will pick up as we go along. You just need to remember that you must not use any of them for any other purposes.


We won't go into the detail of how the class Hat is defined, since we don't need it at this point. The lines appearing between the braces above are not code; they are actually program comments, since they begin with two successive forwarded slashes. The compiler will ignore anything on a line that follows two successive forward slashes in your Java programs, so you will use this to add explanations to your programs. Generally the more useful comments you can add to your programs, the better. We will see in Chapter 2 that there are other ways you can write comments in Java.

Each object of your class will have a particular set of values defined that characterize that particular object. You could have an object of type CowboyHat, which might be defined by values such as "Stetson" for the name of the hat, "White" for the color, and the size as 7.


The parameters defining an object are not necessarily fixed values though. You would expect the name and size attributes for a particular CowboyHat object to stay fixed since hats don't usually change their size, but you could have other attributes. You might have state for example, which could indicate whether the hat was on or off the owner's head, or even owner, which would record the owner's name, so the value stored as the attribute owner could be changed when the hat was sold or otherwise transferred to someone else.

Operating on Objects
A class object is not just a collection of various items of data though. The fundamental difference between a class and the complex data types that you find in some other languages is that a class includes more than just data. A class specifies what you can do with an object of the class - that is, it defines the operations that are possible on objects of the class. Clearly for objects to be of any use in a program, you need to decide what you can do with them. This will depend on what sort of objects you are talking about, the attributes they contain, and how you intend to use them.

To take a very simple example, if your objects were numbers, of type Integer for example, it would be reasonable to plan for the usual arithmetic operations; add, subtract, multiply and divide, and probably a few others you can come up with. On the other hand it would not make sense to have operations for calculating the area of an Integer, boiling an Integer or for putting an Integer object on. There are lots of classes where these operations would make sense, but not those dealing with integers.

Coming back to our CowboyHat class, you might want to have operations that you could refer to as putHatOn and takeHatOff, which would have meanings that are fairly obvious from their names, and do make sense for CowboyHat objects. However, these operations would only be effective if a CowboyHat object also had another defining value that recorded whether it was on or off. Then these operations on a particular CowboyHat object could set this value for the object. To determine whether your CowboyHat was on or off, you would just need to look at this value. Conceivably you might also have an operation changeOwner by which you could set the instance variable recording the current owner's name to a new value. The illustration shows two operations applied in succession to a CowboyHat object.


Of course, you can have any operation for each type of object that makes sense for you. If you want to have a shootHoleIn operation for Hat objects, that's no problem. You just have to define what that operation does to an object.

You are probably wondering at this point how an operation for a class is defined. As we shall see in detail a bit later, it boils down to a self-contained block of program code called a method that is identified by the name you give to it. You can pass data items - which can be integers, floating point numbers, character strings or class objects - to a method, and these will be processed by the code in the method. A method may also return a data item as a result. Performing an operation on an object amounts to 'executing' the method that defines that operation for the object.

Important Of course, the only operations you can perform on an instance of a particular class are those defined within the class, so the usefulness and flexibility of a class is going to depend on the thought that you give to its definition. We will be looking into these considerations more in Chapter 5.


Let's take a look at an example of a complete class definition. The code for the class CowboyHat we have been talking about might look like the following:


This code would be saved in a file with the name CowboyHat.java. The name of a file that contains the definition of a class is always the same as the class name, and the extension will be .java to identify that the file contains Java sourcecode.

The code for the class definition appears between the braces following the identification for the class, as shown in the illustration. The code for each of the methods in the class also appears between braces. The class has three instance variables, owner, size, and hatOn, and this last variable is always initialized as false. Each object that is created according to this class specification will have its own independent copy of each of these variables, so each object will have its own unique values for the owner, the hat size, and whether the hat is on or off.

The keyword private, which has been applied to each instance variable, ensures that only code within the methods of the class can access or change the values of these directly. Methods of a class can also be specified as private. Being able to prevent access to some members of a class from outside is an important facility. It protects the internals of the class from being changed or used incorrectly. Someone using your class in another program can only get access to the bits to which you want them to have access. This means that you can change how the class works internally without affecting other programs that may use it. You can change any of the things inside the class that you have designated as private, and you can even change the code inside any of the public methods, as long as the method name and the number and types of values passed to it or returned from it remain the same.

Our CowboyHat class also has five methods, so you can do five different things with a CowboyHat object. One of these is a special method called a constructor, which creates a CowboyHat object - this is the method with the name, CowboyHat, that is the same as the class name. The items between the parentheses that follow the name of the constructor specify data that is to be passed to the method when it is executed - that is, when a CowboyHat object is created.

Important In practice you might need to define a few other methods for the class to be useful; you might want to compare CowboyHat objects for example, to see if one was larger than another. However, at the moment you just need to get an idea of how the code looks. The details are of no importance here, as we will return to all this in Chapter 5.


Java Program Statements
As you saw in the CowboyHat class example, the code for each method in the class appears between braces, and it consists of program statements. A semicolon terminates each program statement. A statement in Java can spread over several lines if necessary, since the end of each statement is determined by the semicolon, not by the end of a line. Here is a Java program statement:

hatOn = false;

If you wanted to, you could also write this as:

hatOn =
false;

You can generally include spaces and tabs, and spread your statements over multiple lines to enhance readability if it is a particularly long statement, but sensible constraints apply. You can't put a space in the middle of a name for instance. If you write hat On, for example, the compiler will read this as two words.

Encapsulation
At this point we can introduce another bit of jargon you can use to impress or bore your friends - encapsulation. Encapsulation refers to the hiding of items of data and methods within an object. This is achieved by specifying them as private in the definition of the class. In the CowboyHat class, the instance variables, owner, type, size, and hatOn were encapsulated. They were only accessible through the methods defined for the class. Therefore the only way to alter the values they contain is to call a method that does that. Being able to encapsulate members of a class in this way is important for the security and integrity of class objects. You may have a class with data members that can only take on particular values. By hiding the data members and forcing the use of a method to set or change the values, you can ensure that only legal values are set.

We mentioned earlier another major advantage of encapsulation - the ability to hide the implementation of a class. By only allowing limited access to the members of a class, you have the freedom to change the internals of the class without necessitating changes to programs that use the class. As long as the external characteristics of the methods that can be called from outside the class remain unchanged, the internal code can be changed in any way that you, the programmer, want.

A particular object, an instance of CowboyHat, will incorporate, or encapsulate, the owner, the size of the object, and the status of the hat in the instance variable hatOn. Only the constructor, and the putHatOn(), takeHatOff(), changeOwner(), and getSize() methods can be accessed externally.

Important Whenever we are referring to a method in the text, we will add a pair of parentheses after the method name to distinguish it from other things that have names. Some examples of this appear in the paragraph above. A method always has parentheses in its definition and in its use in a program, as we shall see, so it makes sense to represent it in this way in the text.


Classes and Data Types
Programming is concerned with specifying how data of various kinds is to be processed, massaged, manipulated or transformed. Since classes define the types of objects that a program will work with, you can consider defining a class to be the same as defining a data type. Thus Hat is a type of data, as is Tree, and any other class you care to define. Java also contains a library of standard classes that provide you with a whole range of programming tools and facilities. For the most part then, your Java program will process, massage, manipulate or transform class objects.

There are some basic types of data in Java that are not classes, and these are called primitive types. We will go into these in detail in the next chapter, but they are essentially data types for numeric values such as 99 or 3.75, for single characters such as 'A' or '?', and for logical values that can be true or false. Java also has classes that correspond to each of the primitive data types for reasons that we will see later on so there is an Integer class that defines objects that encapsulate integers for instance. Every entity in your Java program that is not of a primitive data type will be an object of a class - either a class that you define yourself, a class supplied as part of the Java environment, or a class that you obtain from somewhere else, such as from a specialized support package.

Classes and Subclasses
Many sets of objects that you might define in a class can be subdivided into more specialized subsets that can also be represented by classes, and Java provides you with the ability to define one class as a more specialized version of another. This reflects the nature of reality. There are always lots of ways of dividing a cake - or a forest. Conifer for example could be a subclass of the class Tree. The Conifer class would have all the instance variables and methods of the Tree class, plus some additional instance variables and/or methods that make it a Conifer in particular. You refer to the Conifer class as a subclass of the class Tree, and the class Tree as a superclass of the class Conifer.

When you define a class such as Conifer using another class such as Tree as a starting point, the class Conifer is said to be derived from the class Tree, and the class Conifer inherits all the attributes of the class Tree.

Advantages of Using Objects
As we said at the outset, object-oriented programs are written using objects that are specific to the problem being solved. Your pinball machine simulator may well define and use objects of type Table, Ball, Flipper, and Bumper. This has tremendous advantages, not only in terms of easing the development process, but also in any future expansion of such a program. Java provides a whole range of standard classes to help you in the development of your program, and you can develop your own generic classes to provide a basis for developing programs that are of particular interest to you.

Because an object includes the methods that can operate on it as well as the data that defines it, programming using objects is much less prone to error. Your object-oriented Java programs should be more robust than the equivalent in a procedural programming language. Object-oriented programs take a little longer to design than programs that do not use objects since you must take care in the design of the classes that you will need, but the time required to write and test the code is sometimes substantially less than that for procedural programs. Object-oriented programs are also much easier to maintain and extend.
_________________________
My New site OpenEyes