March 9, 2021
Hot Topics:

Moving from Procedural to Object-Oriented Development

  • By Matt Weisfeld
  • Send Email »
  • More Articles »


As you learned earlier, methods implement the required behavior of a class. Every object instantiated from this class has these methods. Methods may implement behaviors that are called from other objects (for example, messages) or provide internal behavior of the class.

Internal behaviors are private methods that are not accessible by other objects. In the Person class, the behaviors are getName(), setName(), getAddress(), and setAddress(). These methods allow other objects to inspect and change the values of the object's attributes. This is common design in OO systems. In all cases, access to attributes within an object should be controlled by the object no other object should directly change an attribute of another.


Messages are the communication mechanism between objects. For example, when Object A invokes a method of Object B, Object A is sending a message to Object B. Object B's response is defined by its return value. Only the public methods, not the private methods, of an object can be invoked by another object. The following code illustrates this concept:

public class Payroll{
    String name;
    Person p = new Person();
    String = p.setName("Joe");
    ... code
    String = p.getName();

In this example (assuming that a Payroll object is instantiated), the Payroll object is sending a message to a Person object, with the purpose of retrieving the name via the getName() method. Again, don't worry too much about the actual code, as we are really interested in the concepts. We will address the code in detail as we progress through the series.

Using UML to Model a Class Diagram

Over the years, many tools and models have been developed to assist in designing classes. The most popular tool today is UML. Although it is beyond the scope of this series to describe UML in fine detail, we will use UML class diagrams to illustrate the classes that we build. In fact, we have already used a class diagram. Figure 8 shows the Person class diagram we discussed earlier.

Figure 8 - The Person class diagram.

Again, notice that the attributes and methods are separated (the attributes on the top, and the methods on the bottom). As we delve more deeply into OO design, these class diagrams will get much more sophisticated and convey much more information on how the different classes interact with each other.


One of the primary advantages of using objects is that the object need not reveal all its attributes and behaviors. In good OO design (at least what is generally accepted as good), an object should reveal only the interfaces needed to interact with it.

Details not pertinent to the use of the object should be hidden from other objects. This is called encapsulation. For example, an object that calculates the square of a number must provide an interface to obtain the result. However, the internal attributes and algorithms used to calculate the square need not be made available to the requesting object. Robust classes are designed with encapsulation in mind. In the next sections, we cover the concepts of interface and implementation, which are the basis of encapsulation.


As discussed earlier, the interface is the fundamental means of communication between objects. Each class design specifies the interfaces for the proper instantiation and operation of objects. Any behavior that the object provides must be invoked by a message sent using one of the provided interfaces. The interface should completely describe how users of the class interact with the class. In Java, the methods that are part of the interface are designated as public.

Private Data

In accepted OO design, all attributes should be declared as private. Thus, attributes are not part of the interface. Only the public methods are part of the class interface. Declaring an attribute as public breaks the concept of data hiding.

Let's look at the example just mentioned: calculating the square of a number. In this example, the interface would consist of two pieces:

  • How to instantiate a Square object
  • How to send a value to the object and get the square of that value in return

Interfaces do not normally include attributes, only methods. If a user needs access to an attribute, a method is created to return the attribute (a getter). If a user wants the value of an attribute, a method is called that returns the value of the attribute. In this way, the object that contains the attribute controls access to it. This is of vital importance, especially in testing and maintenance.

If you control the access to the attribute, when a problem arises, you do not have to worry about tracking down every piece of code that might have changed the attribute. It can only be changed in one place (the setter).

Interfaces vs. Interfaces

It is important to note that there are interfaces to the classes as well as the methods—don't confuse the two. The interfaces to the classes are the public methods, whereas the interfaces to the methods relate to how you call them.


Only the public attributes and methods are considered the interface. The user should not see any part of the implementation interacting with an object solely through class interfaces. In the previous example, for instance the Employee class, only the attributes were hidden. In many cases, there will be methods that also should be hidden and thus not be part of the interface. Continuing the example of the square root from the previous section, the user does not care how the square root is calculated as long as it is the correct answer. Thus, the implementation can change and it will not affect the user's code.

A real-world example of the interface/implementation paradigm

Figure 9 illustrates the interface/implementation paradigm using real-world objects rather than code. The toaster obviously requires electricity. To get this electricity, the cord from the toaster must be plugged into the electrical outlet, which is the interface. All the toaster needs to do to get the required electricity is to use a cord that complies with the electrical outlet specifications; this is the interface between the toaster and the electricity. The fact that the actual implementation is a coal-powered electric plant is not the toaster's concern. In fact, for all the toaster cares, the implementation could be a nuclear power plant or a local power generator. With this model, any appliance can get electricity, as long as it conforms to the interface specification seen in Figure 9.

Figure 9 - Power plant example.

A Java example of the interface/implementation paradigm

Let's explore the Square class further. Assume that you are writing a class that calculates the squares of integers. You must provide a separate interface and implementation. That is, you must provide a way for the user to invoke and obtain the square value. You must also provide the implementation that calculates the square; however, the user should not know anything about the specific implementation. Figure 10 shows one way to do this. Note that in the class diagram, the plus sign (+) designates public and the minus sign (-) designates private.

Thus, you can identify the interface by the methods, prefaced with plus signs.

Figure 10 - The square class.

This class diagram corresponds to the following code:

public class IntSquare {
    // private attribute
    private int squareValue;
    // public interface
    public int getSquare (int value) {
        SquareValue =calculateSquare(value);
        return squareValue;
    // private implementation
    private int calculateSquare (int value) {
        return value*value;

Note that the only part of the class that the user has access to is the public method getSquare(), which is the interface. The implementation of the square algorithm is in the method calculateSquare(), which is private. Also notice that the attribute SquareValue is private because users do not need to know that this attribute exists. Therefore, we have hidden the part of the implementation: The object only reveals the interfaces the user needs to interact with it, and details that are not pertinent to the use of the object are hidden from other objects.

If the implementation were to change—say, you wanted to use Java's built-in square function—you would not need to change the interface. The user would get the same functionality, but the implementation would have changed. This is very important when you're writing code that deals with data; for example, you can move data from a file to a database without forcing the user to change any application code.


At this point we are about 2/3 of the way into our discussion on basic object-oriented concepts. Next month, we will conclude the introduction phase of this series and cover the important topics of inheritance, polymorphism, and composition.

About the Author

Matt Weisfeld is a faculty member at Cuyahoga Community College (Tri-C) in Cleveland, Ohio. Matt is a member of the Information Technology department, teaching programming languages such as C++, Java, and C# .NET, as well as various Web technologies. Prior to joining Tri-C, Matt spent 20 years in the information technology industry gaining experience in software development, project management, business development, corporate training, and part-time teaching. Matt holds an MS in computer science and an MBA in project management.

The articles in this series are adapted from The Object-Oriented Thought Process (published by Sams Publishing). Matt has published two other computer books, and more than a dozen articles in magazines and journals such as Dr. Dobb's Journal, The C/C++ Users Journal, Software Development Magazine, Java Report, and the international journal Project Management. Matt has presented at conferences throughout the United States and Canada.

Page 3 of 3

This article was originally published on February 25, 2004

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date