Brief: Object Oriented Programming (OOP) holds many promises for software developers such as higher quality, higher productivity, and reusability. Conventional wisdom may lead you to believe that OOP concepts are difficult to learn. This article takes a unique approach to explaining these concepts by building on your existing AS/400 knowledge.
So much has been said and written about Object Oriented Programming that it seems to have taken on a mystical and magical reputation. Object Oriented Programming (OOP) is not mystical or magical; it is simply good solid programming practices, coupled with complementary tools that allow programmers to increase their productivity by as much as 25 times. This article will introduce some of the basic OOP terminology and concepts. Future articles will further explain OOP programming techniques, benefits, and implementation considerations.
AS/400 programmers moving into OOP have the advantage of capitalizing on their AS/400 background since the AS/400 today is object-based, a subset of fully object-oriented. Add the capability of inheritance, and the ability to define your own classes, and the AS/400 would be fully object-oriented.
While references and comparisons to current AS/400 architectures may not be 100 percent correct, the object concepts that can be related and used can be a valuable education aid.
To gain a better understanding of OOP, it is helpful to first examine two weaknesses of traditional programming techniques. Dealing with complexity within large software projects is one of the areas where current programming techniques are ineffective. Traditional programming is also not designed for reuse and interchangeability.
Traditional Programming Problems
With any nontrivial software project, productivity and quality suffer when programmers are forced to deal with complex user requirements, large data structures, data structure relationships to other structures, sophisticated programming interfaces, and interactions with numerous programmers. The net result is that the demands on many of today's applications have simply exceeded application development capabilities using traditional software production techniques. This is why we are seeing lower programming productivity, more over-budget projects, and significant software quality problems.
For the most part, applications are created from scratch in a custom manner much like manufacturing operated before the advent of interchangeable parts. Guns used to be produced by gunsmiths who custom-built each part. Gun parts were not interchangeable, nor reusable. As we all know, gunsmiths and manufacturing in general no longer operate this way.
Consider the impacts to our lives if manufacturing still operated with noninterchangeable parts. Replacement car parts would have to be custom-built when needed, glass would have to be specially cut to replace broken windows, clothes would be tailored to fit each of us as individuals, and so on. This scenario is almost unimaginable, however software parts today remain neither interchangeable or reusable. This limitation combined with increasing application complexities, slows productivity and decreases quality immensely.
What Is Object Oriented Programming?
OOP provides programmers with some techniques and tools to address the concerns facing programmers who use traditional software development techniques. To describe OOP, we will first define objects, classes, encapsulation, polymorphism, and inheritance. A description of how these items are used together to create object-oriented applications will then give you a better understanding of the benefits to be gained from OOP.
Objects
An object is simply data elements and associated software logic (subroutines) encapsulated within a software structure. 1 shows a representation of an OOP object. The data elements in the inner circle are called instance variables and the associated subroutines in the outer ring are called methods. Because the methods are part of the object, the object can be thought of as active.
An object is simply data elements and associated software logic (subroutines) encapsulated within a software structure. Figure 1 shows a representation of an OOP object. The data elements in the inner circle are called instance variables and the associated subroutines in the outer ring are called methods. Because the methods are part of the object, the object can be thought of as active.
Classes
Objects are defined by classes by simply specifying the instance variables and associated methods that will reside within a particular object. A class is itself an object. It does not contain any data but it defines a "model" for other objects. An AS/400 file object can be viewed within the generic OOP object model diagram, as shown in 2.
Objects are defined by classes by simply specifying the instance variables and associated methods that will reside within a particular object. A class is itself an object. It does not contain any data but it defines a "model" for other objects. An AS/400 file object can be viewed within the generic OOP object model diagram, as shown in Figure 2.
The AS/400 has objects of class type *USRPRF, *OUTQ, *MSGQ, and so on. Using OOP programming techniques, programmers can create and use objects that have their functions and data neatly integrated together. The programmer can create reusable objects using classes such as *SAVINGS ACCOUNT, *CHECKING ACCOUNT, and *INVOICE. This helps programmers to deal with the challenges of creating large and complex applications.
Objects are created from classes as previously mentioned. Similar to the structure of a *FILE object created from DDS specifications on the AS/400, OOP programmers specify the class' contents by defining instance variables. These act as storage slots for objects-just as DDS-described field names act as storage slots for file field contents.
Classes also provide the capability to code methods, which are similar to traditional subroutines, within the object. For example, using full OOP capabilities, a class could be created for a *FILE object that specifies the instance variables (fields) in the *FILE. The class could also define all the methods that act on the *FILE, such as a weekly sales report, a save file operation, a data update task, and so forth.
An example of a user-created class could be a "Credit Card Account" as shown in 3. This class contains all the relevant instance variables (fields), such as the person's name, phone, and credit limit, plus object methods to set the credit limit or determine remaining available credit. From a class, any number of objects can be created. Following our example, the credit institution could create, from the "Credit Card Account" class, individual objects for each credit card customer.
An example of a user-created class could be a "Credit Card Account" as shown in Figure 3. This class contains all the relevant instance variables (fields), such as the person's name, phone, and credit limit, plus object methods to set the credit limit or determine remaining available credit. From a class, any number of objects can be created. Following our example, the credit institution could create, from the "Credit Card Account" class, individual objects for each credit card customer.
Encapsulation
Encapsulation has two properties. First is the built-in restriction of objects to disallow access to its internal instance variables. Only the object's methods have access to the object's instance variables. This property eliminates traditional software bugs caused by misguided manipulation of data elements-a frequent occurrence with large software projects. The result is higher quality software.
AS/400 files use encapsulation for instance variables such as object size, owner, last change date, and so forth. Only AS/400 file methods can change these instance variables. Similarly, a *CHECKING ACCOUNT could encapsulate account transaction details such as the transaction time, teller, verification number, and any other data that should not be directly manipulated.
The second property associated with encapsulation allows the hiding of object- method implementation details from users of an object. This allows changes to be made in the implementation of an application, if desired, without affecting other objects.
For example, let's say a data storage object is responsible for storing data. Other objects that use the data storage object simply supply the data to be saved, and the data storage object saves the data. The data storage object currently implements this responsibility by writing the data to a PC file. If the application requirements change down the road and the PC hard drive is no longer large enough, the data storage object could change to write to an AS/400 file with larger storage capabilities. No other objects would have to make any changes. They would simply continue to ask the data storage object to save their data as before.
In traditionally programmed systems, this type of change often ripples through the entire application. Object-oriented applications can be changed much more easily than traditional systems since objects are modularized and implementation details are encapsulated.
Polymorphism
Polymorphism is the ability of individual objects to respond to the same method in a way that is appropriate for its particular object type. For example, if you invoke the same Display Object Description (DSPOBJD) command on an AS/400 *OUTQ (output queue) object and a *FILE object, the output will be different based on the object type. AS/400 programmers can use the DSPOBJD command with any AS/400 object instead of having to know a particular command or method to use for each object type.
In a user-defined object example, the same print method invoked on an *INVOICE and a *CHECKING ACCOUNT would cause different results. The *INVOICE would print itself in a traditional invoice format with such items as balance due, items purchased, and sales tax. The *CHECKING ACCOUNT would print account transactions, balances, interest paid, and so on. This may sound insignificant, but the ability to have objects react differently to the same method simplifies coding, while adding implicit flexibility to OOP applications.
Inheritance
Inheritance is the ability to automatically share or reuse existing instance variables and methods defined in a different class. Object-oriented languages provide the ability to group together classes that logically would share data elements (instance variables) and software code (methods) in order to form a hierarchy that provides for automatic sharing of data and function.
For example, all AS/400 objects share instance variables such as object owner, creation date, and date last used. All objects have the functions to react to methods such as DSPOBJD, Work with Objects (WRKOBJ), Save Object (SAVOBJ), and so on. Using OOP inheritance, these common instance variables and common methods can be implemented once, and then shared across all objects.
Through inheritance, objects automatically inherit the instance variables and methods defined within their class and all those derived from higher-level classes (superclasses). Consider this example of the AS/400 object hierarchy in 4.
Through inheritance, objects automatically inherit the instance variables and methods defined within their class and all those derived from higher-level classes (superclasses). Consider this example of the AS/400 object hierarchy in Figure 4.
In 4, instance variables and methods coded within superclasses (*OBJECT and *FILE) are only coded once! Both physical files and logical files inherit all methods and instance variables located in classes *OBJECT and *FILE. The benefits of inheritance are code reuse, higher quality, and higher productivity. In addition, improvements and enhancements made to classes *OBJECT or *FILE are available automatically to all classes that subclass from them (*PHYSICAL FILE and *LOGICAL FILE). Traditional programming techniques often involve copying a subroutine from one program to another to another, which could be called code reuse. However, what must be done if a bug is found in one copy of the subroutine?
In Figure 4, instance variables and methods coded within superclasses (*OBJECT and *FILE) are only coded once! Both physical files and logical files inherit all methods and instance variables located in classes *OBJECT and *FILE. The benefits of inheritance are code reuse, higher quality, and higher productivity. In addition, improvements and enhancements made to classes *OBJECT or *FILE are available automatically to all classes that subclass from them (*PHYSICAL FILE and *LOGICAL FILE). Traditional programming techniques often involve copying a subroutine from one program to another to another, which could be called code reuse. However, what must be done if a bug is found in one copy of the subroutine?
Another example of inheritance could be found by looking at a *CHECKING ACCOUNT and *SAVINGS ACCOUNT. They share instance variables such as account owner, balance, and date opened, and also share methods such as deposit and withdraw. These common instance variables and methods could be created in a superclass called *BANK ACCOUNT with both *CHECKING ACCOUNT and *SAVINGS ACCOUNT as subclasses. The instance variables and methods defined in *BANK ACCOUNT would then be automatically inherited by *CHECKING ACCOUNT and *SAVINGS ACCOUNT objects, resulting in code reuse. Inheritance provides for significantly more code reuse, along with higher quality and productivity, than traditional programming technologies-without the undesired side effects found with traditional forms of code reuse.
Putting it All Together
Although there is more to it, the concepts explained here are combined and implemented to produce software that has much higher levels of code reuse, quality, and flexibility.
To create new applications, needed classes and objects available within the system are assembled with new programmer-created classes and objects in an assembly line manner. Objects work together by sending messages back and forth to each other. The messages actually invoke a particular object method in much the same way that traditional languages use the CALL command to invoke a program or subroutine. Completed applications may consist of just a few classes and objects-or many thousands.
Newly created classes can inherit much of their functionality from previously defined classes and will also be available for future software projects to reuse. As time goes on, the inventory of available reusable objects grows, resulting in a more productive programming staff.
No Aladdin's Lamp
In summary, Object Oriented Programming is not a magical tool that will immediately solve all of your software problems. It is the implementation of software development concepts using OOP tool support that will allow programmers to break away from the weaknesses slowing traditional software engineering and to become more productive while producing higher quality software.
Paul Holm is an object-oriented consultant for IBM's AS/400 Division. He is focused on helping IBM customers and business partners design and implement applications using object-oriented techniques.
Object Oriented Programming Concepts
Figure 1 Generic Object
UNABLE TO REPRODUCE GRAPHIC
Object Oriented Programming Concepts
Figure 2 AS/400 File Object
UNABLE TO REPRODUCE GRAPHIC
Object Oriented Programming Concepts
Figure 3 Credit Card Account Class and Object
UNABLE TO REPRODUCE GRAPHIC
Object Oriented Programming Concepts
Figure 4 AS/400 Object Hierarchy
UNABLE TO REPRODUCE GRAPHIC
LATEST COMMENTS
MC Press Online