BIG
DATA

JAVA

CLASS AND OBJECTS IN JAVA

Read more about »
  • Java 9 features
  • Read about Hadoop
  • Read about Storm
  • Read about Storm
 

Why an Object?

You must be wondering what is so revolutionary about looking at the world as objects. The short answer is that focusing on objects makes it easy for us to understand complex things. Objects enable us to look at details that are of interest to us and ignore other details that we are not interested in.

Because so much of this programming style involves objects and classes, we will now look at each of these further.

So what is an Object?

As the name object-oriented implies, objects are key to understanding object-oriented technology. Look around right now and you'll find many examples of real-world objects: your cat, your table, your LED TV, your bicycle, etc.

Real-world objects share two characteristics: They all have state and behavior. Dogs have state (name, color, breed, hungry) and behavior (barking, fetching, wagging tail). Bicycles also have state (current gear, current pedal cadence, current speed) and behavior (changing gear, changing pedal cadence, applying brakes). Identifying the state and behavior for real-world objects is a great way to begin thinking in terms of object-oriented programming.

object

Software objects are conceptually similar to real-world objects: they too consist of state and related behavior. An object stores its state in fields (variables in some programming languages) and exposes its behavior through methods (functions in some programming languages).
Consider a bicycle, for example:

object

By attributing state (current speed, current pedal cadence, and current gear) and providing methods for changing that state, the object remains in control of how the outside world is allowed to use it. For example, if the bicycle only has 6 gears, a method to change gears could reject any value that is less than 1 or greater than 6.

As you can see from the diagrams, the object's variables make up the center or nucleus of the object. Methods surround and hide the object's nucleus from other objects in the program. Packaging an object's variables within the protective custody of its methods is called encapsulation. Typically, encapsulation is used to hide unimportant implementation details from other objects. When you want to change gears on your bicycle, you don't need to know how the gear mechanism works, you just need to know which lever to move. Similarly in software programs, you don't need to know how a class is implemented, you just need to know which methods to invoke. Thus, the implementation details can change at any time without affecting other parts of the program.

This conceptual picture of an object--a nucleus of variables packaged within a protective membrane of methods--is an ideal representation of an object and is the ideal that designers of object-oriented systems strive for. However, it's not the whole story. Often, for implementation or efficiency reasons, an object may wish to expose some of its variables or hide some of its methods.

Bundling code into individual software objects provides a number of benefits, including:

  • Modularity: The source code for an object can be written and maintained independently of the source code for other objects. Once created, an object can be easily passed around inside the system.
  • Information-hiding: By interacting only with an object's methods, the details of its internal implementation remain hidden from the outside world.
  • Code re-use: If an object already exists (perhaps written by another software developer), you can use that object in your program. This allows specialists to implement/test/debug complex, task-specific objects, which you can then trust to run in your own code.
  • Pluggability and debugging ease: If a particular object turns out to be problematic, you can simply remove it from your application and plug in a different object as its replacement. This is analogous to fixing mechanical problems in the real world. If a bolt breaks, you replace it, not the entire machine.

One of the keys to working with objects is knowing how to identify them when you look at system-analysis documents or design documents. Since objects generally represent people, places, or things, a basic method of identifying objects is to pick out the nouns used in a sentence. Here's a simple example. In the sentence "A customer can have more than one bank account," we identify two objects, customer and account. In the sentence, "The car moves," we identify one object, car.



What Are Messages?

The first step in OOP is to identify all the objects the programmer wants to manipulate and how they relate to each other, an exercise often known as data modeling. Once an object has been identified, it is generalized as a class of objects (think of Plato's concept of the "ideal" chair that stands for all chairs) which defines the kind of data it contains and any logic sequences that can manipulate it. Each distinct logic sequence is known as a method. Objects communicate with well-defined interfaces called messages.

A single object alone is generally not very useful and usually appears as a component of a larger program or application that contains many other objects. Through the interaction of these objects, programmers achieve higher order functionality and more complex behavior. Your bicycle hanging from a hook in the garage is just a bunch of titanium alloy and rubber; by itself the bicycle is incapable of any activity. The bicycle is useful only when when another object (you) interacts with it (starts pedaling).

Software objects interact and communicate with each other by sending messages to each other. When object A wants object B to perform one of B's methods, object A sends a message to object B.

object

Sometimes the receiving object needs more information so that it knows exactly what to do--for example, when you want to change gears on your bicycle, you have to indicate which gear you want. This information is passed along with the message as parameters.

Three components comprise a message:

  • The object to whom the message is addressed (Your Bicycle)
  • The name of the method to perform (changeGears)
  • Any parameters needed by the method (lower gear)
object

These three components are enough information for the receiving object to perform the desired method. No other information or context is required.

The Benefits of Messages
  • An object's behavior is expressed through its methods, so (aside from direct variable access) message passing supports all possible interactions between objects.
  • Objects don't need to be in the same process or even on the same machine to send and receive messages back and forth to each other.


Class

In the real world, you often have many objects of the same kind. For example, your bicycle is just one of many bicycles in the world. Using object-oriented terminology, we say that your bicycle object is an instance of the class of objects known as bicycles. Bicycles have some state (current gear, current cadence, two wheels) and behavior (change gears, brake) in common. However, each bicycle's state is independent of and can be different from other bicycles.

When building bicycles, manufacturers take advantage of the fact that bicycles share characteristics by building many bicycles from the same blueprint--it would be very inefficient to produce a new blueprint for every individual bicycle they manufactured.

In object-oriented software, it's also possible to have many objects of the same kind that share characteristics: rectangles, employee records, video clips and so on. Like the bicycle manufacturers, you can take advantage of the fact that objects of the same kind are similar and you can create a blueprint for those objects. Software "blueprints" for objects are called classes.

Definition: A class is a blueprint or prototype that defines the variables and methods common to all objects of a certain kind.

class

For example, you could create a bicycle class that declares several instance variables to contain the current gear, the current cadence, and so on, for each bicycle object. The class would also declare and provide implementations for the instance methods that allow the rider to change gears, brake, and change the pedaling cadence.

class

The values for instance variables are provided by each instance of the class. So, after you've created the bicycle class, you must instantiate it (create an instance of it) before you can use it. When you create an instance of a class, you create an object of that type and the system allocates memory for the instance variables declared by the class. Then you can invoke the object's instance methods to make it do something. Instances of the same class share the same instance method implementations (method implementations are not duplicated on a per object basis), which reside in the class itself.

In addition to instance variables and methods, classes can also define class variables and class methods. You can access class variables and methods from an instance of the class or directly from a class--you don't have to instantiate a class to use its class variables and methods. Class methods can only operate on class variables--they do not have access to instance variables or instance methods.

The system creates a single copy of all class variables for a class the first time it encounters the class in a program--all instances of that class share its class variables. For example, suppose that all bicycles had the same number of gears. In this case defining an instance variable for number of gears is inefficient--each instance would have its own copy of the variable, but the value would be the same for every instance. In situations such as this, you could define a class variable that contains the number of gears. All instances share this variable. If one object changes the variable, it changes for all other objects of that type.

The following Bicycle class is one possible implementation of a bicycle:


class Bicycle {

    int cadence = 0;
    int speed = 0;
    int gear = 1;

    void changeCadence(int newValue) {
         cadence = newValue;
    }

    void changeGear(int newValue) {
         gear = newValue;
    }

    void speedUp(int increment) {
         speed = speed + increment;   
    }

    void applyBrakes(int decrement) {
         speed = speed - decrement;
    }

    void printStates() {
         System.out.println("cadence:" +
             cadence + " speed:" + 
             speed + " gear:" + gear);
    }
}

The responsibility of creating and using new Bicycle objects belongs to some other class in your application. Here's a BicycleDemo class that creates two separate Bicycle objects and invokes their methods:


class BicycleDemo {
    public static void main(String[] args) {

        // Create two different 
        // Bicycle objects
        Bicycle bike1 = new Bicycle();
        Bicycle bike2 = new Bicycle();

        // Invoke methods on 
        // those objects
        bike1.changeCadence(50);
        bike1.speedUp(10);
        bike1.changeGear(2);
        bike1.printStates();

        bike2.changeCadence(50);
        bike2.speedUp(10);
        bike2.changeGear(2);
        bike2.changeCadence(40);
        bike2.speedUp(10);
        bike2.changeGear(3);
        bike2.printStates();
    }
}

The output of this test prints the ending pedal cadence, speed, and gear for the two bicycles:

cadence:50 speed:10 gear:2
cadence:40 speed:20 gear:3
How to identify and design a Class?

This is an art; each designer uses different techniques to identify classes. However according to Object Oriented Design Principles, there are five principles that you must follow when design a class,

  • SRP - The Single Responsibility Principle - There should never be more than one reason for a class to change.
  • OCP - The Open Closed Principle - You should be able to extend a classes behavior, without modifying it.
  • LSP - The Liskov Substitution Principle- Subclasses should be substitutable for their base classes.
  • DIP - The Dependency Inversion Principle- Depend upon Abstractions. Do not depend upon concretions.
  • ISP - The Interface Segregation Principle- Make fine grained interfaces that are client specific. Many client specific interfaces are better than one general purpose interface.

Objects provide the benefit of modularity and information hiding. Classes provide the benefit of reusability. Bicycle manufacturers reuse the same blueprint over and over again to build lots of bicycles. Software programmers use the same class, and thus the same code, over and over again to create many objects.

Benefits

The benefits of organizing software into object classes fall into three categories:

  • Rapid development
  • Ease of maintenance
  • Reuse of code and designs

Object classes facilitate rapid development because they lessen the semantic gap between the code and the users. System analysts can talk to both developers and users using essentially the same vocabulary, talking about accounts, customers, bills, etc.

Object classes facilitate ease of maintenance via encapsulation. When developers need to change the behavior of an object they can localize the change to just that object and it's component parts. This reduces the potential for unwanted side effects from maintenance enhancements.

Classes facilitate re-use via inheritance and interfaces. When a new behavior is required it can often be achieved by creating a new class and having that class inherit the default behaviors and data of its superclass and then tailor some aspect of the behavior or data accordingly. Re-use via interfaces (aka methods) occurs when another object wants to invoke (rather than create a new kind of) some object class. This method for re-use removes many of the common errors that can make their way into software when one program re-uses code from another.