Java for the PLSQL Developer

Java for the PL/SQL Developer

If you are a PL/SQL programmer and are new to Java, comparing the syntax and structure of a language you already know to a new language may help you get started with adding Java to your pool of programming skills. In many ways, matching PL/SQL up to Java is an apples to oranges comparison; however, as with all general purpose programming languages, there are also many things in common.

After reading this section, PL/SQL programmers will understand the basic differences between PL/SQL and Java. If you are already a knowledgeable Java programmer, you can either skip this section, or continue reading to refresh your Java knowledge.

Learning Java

As a PL/SQL developer, you may wonder if you need to learn how to program in Java. Because developers write entire applications in Java, as well as components at every tier of the application architecture, knowing how to program in Java is an important skill for all Oracle developers. Even though Oracle continues to improve PL/SQL, it is nonetheless a proprietary language. Java is not proprietary, and is useful in developing programs on a variety of platforms. As more business logic moves out of the database tier and into a middle tier , PL/SQL will play less of a role in new application development.

This is not to say that you should write all future programs in Java rather than PL/SQL. On the contrary, there are many tasks where PL/SQL is a more suitable programming language than Java, such as ones with heavy data manipulation. Rather, Java is another tool that a programmer can choose from when developing software.

Although PL/SQL now contains object-oriented features, the structure of a typical PL/SQL program is top-down programming. In contrast, Java is a pure object-oriented language, and as such is more difficult to learn. While the syntax of Java is relatively simple to learn, the difficult part is modeling objects in an efficient and clear manner. C and C++ programmers will instantly notice that the syntax and structure of Java programs closely resembles these languages, and all of the efficient constructs such as x++ (add 1 to x), y+=z (add z to y), and (a>b)?a:b (determine the greater of a and b) are available in Java as well. Java is especially similar to C++, the object-oriented version of C, but with important differences such as no pointers, no multiple inheritance, and automatic memory allocation and garbage collection.

Object-Oriented Program Features

Object-oriented programming languages, including Java, share several features that demonstrate the capabilities of developing in objects. Well-designed objects perform discrete functions and are often reusable, such that a specific function is only in one object. In many respects, designing an object-oriented application is analogous to normalizing a data model.

Features of all object-oriented languages include:

  • Classes A program unit, consisting of attributes and methods .

  • Constructor methods Code that is automatically executed when memory is allocated for an object.

  • Encapsulation The capability to protect attributes and methods so that calling programs cannot access the attributes and methods directly.

  • Inheritance Allows classes to be built in a hierarchical fashion.

  • Packages A group of related classes.

  • Polymorphism The capability of an object to respond to the same message in specific ways: Objects can have different implementations of the same message.

PL/SQL supports some, but not all of these features, as described below.

Classes

Java programs, as with all object-oriented languages, use templates called classes that define objects having common characteristics. The concept of a class is a difficult topic for programmers to learn who are new to object-oriented thinking, as there is no equivalent construct in top-down programming. On the plus side, once you understand the concept of a class, you are well on your way to being an object-oriented programmer.

In general, classes are object templates that contain either or both of the following:

  • Attributes Attributes are similar to variables in PL/SQL. The data type for an attribute is either a native data type or a class.

  • Methods Methods are similar to procedures and functions in PL/SQL. Methods either return a data type (as with PL/SQL functions), or use the keyword void specifying that no data type is returned (as with PL/SQL procedures).

Java programs allocate memory for objects defined by a class using a process called instantiation. An attribute or object variable stores the reference to the object, and the object holds the data for a single occurrence of the class. A program can create multiple instances of the same class. A small example is a purchase order class that defines all of the characteristics and business functions for a purchase order, and purchase order 1000 is a physical instance of the purchase order class.

In many ways, a class is like a PL/SQL package, as packages also contain variables, stored procedures, and functions. However, in other ways, a class is like a table, as each instance of the class contains data for one table row (a class can also be an entire table ”i.e., a vector).

For example, attributes shapeSquare and shapeTriangle both store references to objects defined by the Shape class; in other words, the data type of both attributes is a Shape object. Attributes whose data type is an object are instantiated by using the new keyword. This following class example also contains an attribute named area whose data type is a native Java double-precision floating-point number. The Shape class contains a method named calcArea that does not take any parameters.

 public class MyShapes {    public static void main(String args[]) {       Shape  shapeSquare   = new Shape("square",3.0);       Shape  shapeTriangle = new Shape("triangle",2.0,4.0);       double area;       area = shapeSquare.calcArea();       System.out.println("area of the square equals " + area);    } } 
Note  

Before the Java purists get upset with me, note that there is a better way to do this, as we ll see below. We will build off of this example.

It is important to notice the use of capitalization in the MyShapes class example. Unlike PL/SQL, Java is case-sensitive, and Java keywords such as public, class, new, and double must be lowercase. By convention, capitalize the first letter of every word within a class name; for example, MyShapes. Also by convention, capitalize the first letter of every word within an attribute and method name , except for the first letter. Attributes shapeSquare and shapeTriangle, and the Shape method getArea demonstrate this convention.

Another difference between PL/SQL and Java variables is the use of quotes around string values. Whereas PL/SQL requires single quotes around strings, Java requires double quotes. In Java, as in C, single quotes define a character.

Constructor Methods

All Java methods support parameter overloading, where the class contains multiple versions of the same method, and the parameters passed to the method determine which version of the method to execute. Consequently, each class may contain one or more constructor methods, often referred to as constructors. Recall that constructors are methods that the JVM executes automatically when an object is instantiated, and are useful for initializing variables and environment setup. Within a class, constructors have the same name as the class name, and do not specify a return data type. All other methods within the class must specify a return data type, where methods that do not return a value specify void for the return data type.

Upon instantiation of an object, the JVM automatically executes the constructor matching the parameter list passed using the new statement. Multiple constructors are a way to set default values for parameter values. A constructor with fewer parameters usually calls another constructor using the keyword this, a system variable that contains a reference to the class itself, passing in default values for the missing parameters.

In the MyShapes class example, the Shape constructor for the shapeSquare attribute receives two parameters, a string, and a double precision floating-point number. For shapes such as squares, both the width and height dimensions require the same value, so the constructor only requires one dimension parameter. The Shape constructor for the shapeTriangle attribute requires three parameters, a string, and separate numbers for the width and height values.

The Shape class contains the two required constructors. This example demonstrates how the first constructor calls the second constructor with the same value for the second and third parameters.

 public class Shape {    private String shapeName;    private double width, height;    public Shape(String s,double x) {          // First constructor      // Call the second constructor passing the same String parameter,      // and the double parameter for the second and third parameters      this(s,x,x);    }    public Shape(String s,double x,double y) { // Second constructor       shapeName = new String(s);       width     = x;       height    = y;    }    public double calcArea() {       if (shapeName.equals("square")) {          return width * height;       } else if (shapeName.equals("triangle")) {          return (width / 2.0) * height;       } else { // unknown shape          return 0;       }    } } 

Similar to constructors, PL/SQL package bodies can contain an initialization part that the Relational Database Management System (RDBMS) automatically executes the first time a user session references the package. Because you cannot directly execute a PL/SQL package, only procedures and functions within the package, you cannot pass parameters to, or overload, the initialization part.

 CREATE OR REPLACE PACKAGE my_shapes AS    FUNCTION calc_area RETURN NUMBER; END my_shapes; CREATE OR REPLACE PACKAGE BODY my_shapes AS    shape_name VARCHAR2(20);    width      NUMBER(10,2);    height     NUMBER(10,2);     Initialization part    width  := 0;    height := 0;    FUNCTION calc_area RETURN NUMBER ... END my_shapes; 

Some object-oriented languages also have destructor methods, known as destructors, which execute automatically when destroying or freeing an object. Because Java automatically handles memory allocation, there is no built-in support for destructors within Java classes.

Encapsulation

Encapsulation provides the capability to control which attributes and methods within a class other methods can access. This capability allows the program to control the values set to the attributes, providing an added level of data integrity.

Java uses three keywords to encapsulate classes, attributes, and methods:

  • public Allows access to attributes and methods by any calling program

  • protected Allows access only by related methods

  • private Attributes defined as private within a class are only accessible by methods within the class; methods defined as private within a class are not accessible by the calling program

If an attribute or method does not contain one of these three keywords, the attribute or method has the default package access. To state it another way, the attribute or method is accessible by all other classes within the same package, and not accessible by classes on other packages.

In addition to data integrity, this control also reduces the interdependence between classes. A developer can change the private and protected attributes and methods within a class without affecting other classes, given other classes cannot directly access these attributes and methods.

In the Shape class example, the shapeName, width, and height attributes are all private. The MyShape class example cannot reference these variable values directly. On the other hand, the calcArea method is public, so the MyShape class example can execute this method.

PL/SQL packages provide a similar scheme to encapsulate variables, functions, and procedures. The package specification exposes the public variables, and function and procedure prototypes , that calling programs can access. Variables, functions, and procedures defined only in the package body are private, and are not accessible by the calling programs.

Tip  

Oracle schemas and grants are similar to Java s public and private. They indicate who can get to the objects.

Inheritance

The use of inheritance is a powerful object-oriented characteristic to implement a class hierarchy, and a properly designed class hierarchy is essential in creating modular, reusable objects. A derived, or child, class includes all of the attributes and methods of the parent, or base, class. A calling program that instantiates a derived class has access to the public attributes and methods of the derived class, plus the public attributes and methods of the ancestors of the derived class. If necessary, a derived class can redefine (known as overriding) a method in an ancestor class by defining the method in the derived class with the same name and parameter list.

Java uses the keyword extends to specify that the class will inherit the attributes and methods of the base class. The example below modifies the Shape class example to replace the constructors with a single default constructor that does not take any parameters, and removes all the variables and the calcArea method from the Shape class. Using inheritance, each derived shape class has its own of dimension attributes and area calculation method.

Also, add the keyword abstract to both the Shape class specification and the calcArea method specification. An abstract class restricts calling programs from directly instantiating an object of that class, forcing calling programs to instantiate one of the derived classes instead. Because the Shape class is an abstract class, you can also require that all derived classes code a calcArea method that returns a double precision floating-point number by placing the prototype of the calcArea method, without any code, in the Shape class template. Knowing that all nonabstract subclasses of this class will have the required calcArea() method has important implications for polymorphism, discussed in the next section.

 public abstract class Shape {    public Shape() {}                  // Default constructor    public abstract double calcArea(); // Derived classes must implement } public class Square extends Shape {    private double width;    public Square(double x) {       width = x;    }    public double calcArea() {       return width * width;    } } public class Triangle extends Shape {    private double width, height;    public Triangle(double x,double y) {       width = x;       height = y;    }    public double calcArea() {       return (width / 2.0) * height;    } } 

While there is no definitive right or wrong way to code in Java, most experienced Java developers would acknowledge that this code is closer to the spirit of the Java language.

It is easy to see how adding new shapes does not require any additional changes to the base Shape class, and how all attributes and methods specific to each shape are in their own objects. PL/SQL packages do not support inheritance, although Oracle object types, the equivalent of classes, provide this capability.

Polymorphism

Polymorphism builds on inheritance to allow the developer to create an attribute of a base class, but instantiate the attribute with a derived object. Building on the inheritance example where the Square and Triangle classes extend the Shape class, a single attribute can reference either a Square or a Triangle object. This is a powerful object-oriented feature that significantly reduces the number of attributes and control statements required. Without polymorphism, the calling program would have to declare separate attributes to hold either a Square or a Triangle object. Although this example only has two possible objects, it is easy to imagine hundreds or thousands of possible objects, each requiring a separate attribute.

To demonstrate this feature, replace the MyShapes class with an example using a single attribute named shape whose data type is the base Shape class.

 public class MyShapes {    public static void main(String args[]) {       Shape  shape;       double area;       // Instantiate a Square object into a Shape attribute       shape = new Square(3);       area = shapeSquare.calcArea();       System.out.println("area of the square equals " + area);    } } 

Because the Shape class is an abstract class that requires a calcArea method, the calling program is sure that regardless of what object derived from the Shape class the program instantiates into the shape attribute, the object will have a calcArea() method that returns a double precision floating-point number.

Polymorphism allows for easy processing of all Shape subclasses. For example, if you have an array of Shape subclass objects named shapeList, you could easily sum the areas of all shapes within the array. Without polymorphism, the same calculation would require an IF statement with a test for each type of shape, and would have to change whenever a developer created a new Shape subclass.

 int totalArea = 0; for (int i = 0;i < shapeList.size();i++)    totalArea += ((Shape)shapeList.get(i)).calcArea(); 

In Java, you can raise specific exceptions that must be handled by the calling method; you can t do this in PL/SQL.



Oracle Application Server 10g Web Development
Oracle Application Server 10g Web Development (Oracle Press)
ISBN: 0072255110
EAN: 2147483647
Year: 2004
Pages: 192

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net