Saturday, September 30, 2006

OOP Part 1 - Classes, Methods and Objects

Advantages Of OOP

OOP provides advantages over traditional structural programming languages. OOP facilitates writing applications by turning real-world objects into code components. OOP enables users to model real-world objects. Modeling means representing real-world objects as components in Java. Object-Oriented Programming allows programmers and customers to use the same terminology to explain the business domain and the program.

In Summary:

  • Enables the use of real-world modeling
  • Promotes the reuse of code
  • Provides flexibility in the modification of an existing application
  • Helps with the maintainability of code.
Lets go in detail with the advantages...

Enables the use of real-world modeling

Consider an example. A car is an object that has specific attributes, such as an engine and wheels. Using OOP principles, you would model the car as a car object in Java that would have the same properties.

Creating applications that model the real world closely enables developers to understand an application faster than any other applications. Therefore, an application that implements OOP concepts effectively is implemented and used.

Promotes the reuse of code

Another advantages of OOP is that it promotes the reuse of code. The code used to define an object can be shared by several objects of an application. For Eg: the code used to design a type of car can be used for designing different types of cars. This saves you from rewriting code for various types of cars. A benifit of code reuse is that it reduces the amount of code to write, debug, test, and possibily upgrade in the future.

Provides flexibility in the modification of an existing application

OOP promotes flexibility in the design and implementation of a solution. Maintainance and upgrades are seen as further cycles in application development. By using OOP practices, applications become easier to extend.

Consider an example of XYZ Corporation. The application used by the production department of this organization is currently designated to create two types of chairs, plastic and metal. To meet the demands of its customers, the organization decides to produce wooden chairs as well. To meet the change in the requirement, the XYZ corp. needs to incorporate changes into its current application system. If the current system was built using OOP best practices, extensions to the system may be simplified. For Eg: the new chair type would be able to share or reuse some of the other chair types' code.

Helps with the maintenance of Code

Finally, OOP helps in the maintenane of code. By using OOP, you can create seperate components for different requirements. In OOP, a component is known as a class. For example, to design a payroll system of an organization, you could create classes such as Employee and Payroll. By creating the Employee and the Payroll classes, information related to each class can be segregated. An internal change in one of these classes should not affect the functionality of the other class. Therefore, the maintenance of a system is simplified by reducing dependencies in between classes.

OOP Design Principles

An application that implements Object-Oriented Programming (OOP) concepts is distinguished by four design principles. The four design principles are encapsulation, abstraction, inheritance, and polymorphism.

Encapsulation

Encapsulation hides the inner workings of an object from outside users of the object. This protects outside users from making internal changes or optimizations to such objects. The object needs only to maintain its external functionality to support its clients. Internal details, such as data representation, should not be accessible externally.

Abstraction

The principle of abstraction is modelling real-world objects as objects in Java. However, these objects are only modeled at a certain level of detail. Only the behaviour and data that is needed by your application will be included in your model.

The abstraction design principle focusses on the essential characteristics of an object. In OOP, abstraction defines the conceptual boundaries of an object. These boundaries distinguish one type of object from another.

Inheritance

The inheritance design principle allows a class to inherit the characteritics of another class. When inheritance is used in an application, the application consists of classes that are arranged in hierarchies. The classes defined at the lower levels of a hierarchy inherit from the classes higher up in the hierarchy.

By creating a hierarchy of classes, the characteristics and code of a class are made reusable. A class can inherit characteristics from other classes and provide additional features. The new class has its own attributes and the attribtues of the existing class. This feature provides extensibility and reusability in classes.

Polymorphism

Polymorphism refers to the ability of an object to take on different forms depending upon the situation. Consider an example of a class Sedan that inherits from the class Car that inherits from the class Vehicle. An instance of the Sedan class can be referred to as a Sedan, a Car, or a Vehicle.

Polymorphism provides flexibility to an application based on requirements. It simplifies coding and reduces the rework involved in developing and modifying an application. This is because different types of objects can react to the same type of stimulus.

Classes and Objects

The idea of Object-Oriented Programming (OOP) is to place data and methods together in a single entity. The single entity holding the data and methods is called a class. An Object is an instance of a class.

To create a Java application, you organize programming structures by creating classes that consist of reusable code. You can create a class in Java to perform simple tasks, such as declaring the member variables of the class and perhaps initializing the member variables by using the methods of the class.

An instance of a class is declared the same way that a primitive data type is declared. A class defines both data and methods. You can reuse the same class in several applications withoug rewriting it. You can create as many instances or objects of a class as needed. When multiple objects are created, each object maintians a seperate copy of the member variables defined by the class.


Creating a Class

  1. Specify the class name.
  2. Declare data members.
  3. Declare methods.
  4. Define the processing.
In order to define a class, you must specify the class name, declare the member variables, and declare the methods of the class.

There are certain naming conventions that should be followed when naming a class. First, class names should be nouns. The first character of the class name should be upper case, and each internal word of the name should be upper case. The rest of the characters in the name should be lower case. The words in the name should be whole words. Acronyms and abbreviates should be avoided.

In addition, you must define the processing that is required for the method. For example, operations such as addition or substraction on member variables can be specified in the methods. The contents of the class definition are enclosed within braces.

public class Rectangle {
    //class name and Body begins now...
    int length=10;
    int width=5;
    String color;

void calculateArea() {
      //method declartion
      int totArea = length * width;//processing
      System.out.println("The total area is " + totArea);
    }
}//end class body

Consider the Rectangle class shown above. It consists of the class keyword followed by the class name. The class body befins with an opening brace. The class body consits of member variables and a method. In the method declaration, the member variables are accessed and processed. To end the class declaration you use a closing brace.

A class declared in Java usually contains an access modifier. The access modifier determines the type of access other classes and objects can have to a specific class and the fields and methods that it defines. In our example, Rectangle class is declared using "public" access modifier meaning it can be accessed by anyone.

Access Modifiers

The access modifiers that can be used while declaring a class are public, private, and protected. When the class is declared without an access modifier, the class is accessible by the other classes in the current package. when a class is declared with the public access modifier, the class is accessible by all the other classes.

The private and protected access modifiers may only be used on inner classes. They cannot be used for top-level classes. When a class is declared with the private access modifier, the class is not accessible by any other classes. When a class is declared with the protected access modifier, the class is accessible by subclasses of the class.

In addition to the access modifiers, the modifiers final, abstract, and strictfp may be specified.

If the final modifier is specified, the class represents a complete class and cannot be overridden by a subclass.

The abstract modifier is used to declare that a class is considered incomplete. An abstract class may have abstract methods that are not implemented within the class.The final modifier cannot be used with the abstract modifier.

The strictfp modifier is used to force the code within the entire class to use strict floating-point logic. This applies to all float and double values that are used within the class.

Declaring Methods

A class is defined by its state and behaviour. The member variables of the class define the state of the class. The methods of a class define the behaviour of the class.

Consider an example, To add the values stored in the member variables of a class, you declare a method that operates on these member variables to compute their sum. The result can be displayed by another method that calls the computed method.

The six basic components of a method include the access modifier, other modifiers, the return type of the method, the name of the method, a list of the arguments passed to the method, and the body of the method.

<access modifiers> <other method modifiers>
<return type> methodName(arg1, arg2, ...) {

//method body

}

Access Modifier

It is a Subset of the method modifier group. This specifies the type of access granted to other objects for that method. You can declare a method public, private, or protected. If no access modifier is specified, the method is accessible to all classes in the current package. A public method may be accessed from any class. A protected method may be accessed from any subclass of the class in which the method is defined. A private method may only be accessed from within the class in which it is declared.

void myPackageMethod() {
    // This method may be accessed from any
//class declared in the same package
}

public void myPublicMethod() {
    //This method may be accessed from any class
}

private void myPrivateMethod() {
    // This method cannot be accessed from other classes.
}

protected void myProtectedMethod() {
    // This method may be accessed from any
//subclass of the class that declares it.
}

public final void myFinalMethod() {
    // This method cannot be overridden or hidden
}

public abstract void myAbstractMethod();
//This method must be overridden to create a concrete class

public static void myStaticMethod() {
    //Do Work
}

public native void someExternalMethod(String name);

public strictfp void myStrictFpMethod() {
    // All float and doubles use strict floating point logic.
}

public syncrhornized void mySynchronizedMethod() {
    //Multiple threads will not be able to
//access this method at the same time.
}


Other Method modifiers

In addition to the access modifiers, the modifiers static, final, abstract, native, strictfp, and synchronized may be specified.

Static method are scoped to the class and not to the instance of the object. These methods may be called without an instance of the class being created. These methods may be called without an instance of the class being created. They may access static variables, but do not have direct access to member variables.

If the final modifier is specified, the method cannot be overridden or hidden by a subclass. The abstract modifier is used to declare that a method is not implemented in a class. In this case, the method must be implemented by a subclass in order to create a class that can be instantiated. This final modifier cannot be used with the abstract modifier.

The native modifier is used to define a class that is implemented in code external to the Java Code. This is typically used to allow a Java application to call code in languages such as C++.

The strictfp modifier is used to force the code within the method to use strict floating-point logic. This applies to all float and double values that are used within the method.

The synchronized modifier is used when access to the method needs to be synchronized in order to prevent multiple threads from accessing it at the same time. This can be used to keep multiple threads from modifying variables or accessing resources at the same time.

Return Type

The return type of the method indicates the return type of the method. The return type of the method indicates the type of value that the method provides to a calling method. The return type is specified by a primitive or object data type, such as void, int, char, String, or Date. The return type is always followed by the method name.

Method Name

A method name that follows the int data tyoe would signify that the method returns a type integer when its is involved. Note if the method does not return any type, the method name is preceded by the void return type.

The method name is user-defined and should be meaningful. According to Java variable naming conventions, if a name consists of two or more words, you join the words to form a single word and capitalize the first letter of each word, except for the first word.

The name of the method must not be a Java Keyword, such as int, package, or void. In addition, the method name should not begin with a digit and must not contain embedded spaces or periods. For example, findFile is a valid method name.

If a method defines a return type, then the return keyword is used to return the value. The keyword is followed by the value that is to be returned by the method. note that this keyword is not required if the method does not return a value because its return type is void.

Method Arguments

This is a comma separated list of variable declarations that are defined within enclosing parentheses. Arguments are optional. The parentheses are mandatory.

Method Body

The body contains statements and expressions that run when the method is invoked. The body of the method can have conditions and loops, and it can send messages to other instances or to other objects.

Method Overloading

Programming languages like C require unique names for different methods in the same program. In Java, you can declare methods with the same name. This process is called method overloading.

In C, a program contains many methods that perform different tasks. Therefore, it is difficult for an application developer to remember the function and name of each method.

In Java, you can declare methods with the same name. However, these methods must accept different arguments. This process of declaring methods with the same name is called method overloading.

In Java, every method has a signature, which consists of a method name and an argument list. The data type of the arguments and their sequence helps define the signature of a method.

A Class cannot have two methods with the same signature. This is because compiler will not be able to determine which method to invoke.

In addition to overloading a method with a different number of arguments, you can overload a method by specifying different data types for the arguments. You can also overload a method by providing a different sequence for arguments.

void addNum(int num, float num1)
void addNum(float num, int num1)

Consider an example in which you declare a method that adds an integer value and a float value. In such situation, a user can pass an integer value first and then the float value or vice-versa. To conform to this requirement, you declare two methods with a different sequence of arguments but with the same name.

Pass By Value: Primitives

When you invoke a method, you may pass arguments to the method. The arguments are used by the method. Either the value of the argument or a reference to an object are passed.
When you invoke a method by passing arguments by value, it is know as passing by value. When you invoke a method by passing a value to a method, it is known as passing arguments by value. Java passes all method arguments by value for primitive data types. By passing the arguments by value, the original value of arguments is not altered inside the method. The method only receives a copy of the variable.

void computePrice(int unitPrice, int numberOfUnits) {
   unitPrice = unitPrice * numberOfUnits;
   System.out.println("unitPrice in the computePrice method : "
+ unitPrice);
}

For example, to calculate the total price for four identical items, you multiply the unit price of the item by four. This will not change the price of the individual item. This is because the price was passed by value.
When you invoke a method by passing a value, a local copy of each argument is made in the called method. Consider the code of the item class shown in the above example. This class contains the computePrice method. This method has a piece of code that changes the value of the unitPrice parameter. The computePrice method calculates the price of the number of items and stores the total in the unitPrice variable. The method also displays the total value.

In Summary: Calling a method and passing the arguments by value does not affect the original value.

Pass By Reference: Objects

Whenever arguments of type Object are passed to a method, their references are passed as opposed to a copy of the object. An object is passed by reference when it is an argument of a method. This ensures that the changes to the object are retained because the actual object is being updated.

class Employee {
    String name;
String department;
double salary;



public Employee(String empName, String empDept, double empSalary) {
        this.name = empName;
this.department = empDept;
this.salary = empSalary;
    }
    void printAll() {
        System.out.println("Name : " + name);
System.out.println("Department : " + department);
System.out.println("Salary : " + salary);
    }
    public static void main(String args[]) {
        Employee jane = new Employee("Jane", "Research", 60000);
Employee tempEmp = jane;
tempEmp.name = "Tom";
jane.printAll();
    }
}

Consider a situation where each employee is assigned three details. These details are name, department, and salary. In addition, an employee can print all the details through the printAll method. The sample code in the example instantiates a new Employee object, bound to the variable jane. The code then assigns Jane to the name, Research to the department, and 60000 to the salary. Next, a variable of type Employee called tempEmp is declared and assigned to the same instance that the variable jane is bound to. Both jane and tempEmp are references pointing to the same object. A change to one will be reflected in the other.

No comments: