ISTE Home
About ISTE
Advocacy
Educator Resources
Membership
Affiliates
Awards & Recognition
ISTE 100
Join or Renew
Member Campaigns
Member Central
Member Networking
My Profile
Podcasts
Premium
Special Interest Groups
SIG Newsletter
Join a SIG
Join SIGCT
SIGCT Officers
Journal for Computing Teachers (JCT)
JCSE Online - Journal of Computer Science Education
Past Issues
2005-2006
2004-2005
2003-2004
2002-2003
2001-2002
April 2002
February 2002
November 2001
October 2001
Submission Guidelines
SIGCT & NCWIT
SIG Directory
SIG Projects & Archives
SIG Wikis, Listserves & Ning
Volunteer
ISTE 2010
NETS
Career Center
News & Events
Professional Development
Publications
Research
Store

Printer Friendly
Members Only Members Only

Pedagogical Issues in Object Orientation

Sridhar Nerur, Sam Ramanujan, and Someswar Kesh
Central Missouri State University

Abstract
There is an urgent need for people with object-oriented (OO) skills. Though OO may not be a panacea, it is widely acknowledged that it can at least alleviate some of the problems encountered by traditional approaches to software development. The gains in productivity, quality, and development time and the ease of extending systems make OO an attractive alternative to the structured approach. The kind of attention that OO has received has compelled academics to offer courses based on the OO paradigm, with a view to preparing their students for what appears to be the wave of the future. This article addresses some of the difficulties in teaching OO and presents some of the lessons we have learned in our efforts to educate our students on the principles of OO.

The structured approach to software development has been the dominant paradigm in systems development for many years. Courses dealing with this paradigm focused on data flow diagrams, the entity-relationship model, structure charts, pseudo-code, and programming constructs such as sequence, iteration (e.g., do..while, for loops, etc.,), and selection (e.g., if..then..else, case, etc.,). The emphasis was on top-down functional decomposition and the level of abstraction could best be described as algorithmic or procedural. Some of the problems with the traditional approach (Korson & McGregor, 1990; Meyer, 1988) include:

  • lack of a unifying model to integrate analysis, design, and implementation;
  • no encouragement for reusability; and
  • that evolutionary changes are scarcely taken into account, often resulting in systems that are not resilient.

The object-oriented (OO) approach to software development requires an entirely different way of looking at problems (Marion et al., 1996a). This approach emphasizes modeling the problem and may, therefore, result in better problem understanding. The experiences of some of the companies that have embarked on the OO journey shows that more time needs to be spent on analysis than on programming (Marion et al., 1996a, 1996b). Reusability of components and flexibility of a system arise from good analysis and design, not from the mere use of an OO language such as Java or C++. A good grasp of OO principles is not possible without a change in one’s perceptual world or worldview (as we try to show throughout the article). This article shares some of our experiences in teaching OO. It also attempts to provide some preliminary answers to the following questions:

Should we move to modeling problems directly, emphasizing analysis and design, rather than continue to create data abstractions that (perhaps inadvertently) emphasize implementation?

Does the choice of an implementation language affect student learning of OO concepts?

The Nature of the Problem

The evolution of programming languages has seen a steady progression from a lower level of abstraction (i.e., the computer architecture) to a higher level (the problem domain). There is an increasing level of consistency between the end user’s perception of reality (or the problem domain) and the developer’s mapping of the domain into an implementation language. At one end of the spectrum is machine language, which requires an intimate knowledge of computer hardware. Assembly language also requires a good grasp of the architecture of the machine on which the program has to be executed. The imperative languages, such as C and Pascal, are characterized by procedural or algorithmic abstraction, typically top-down functional decomposition of the problem, and a hierarchy that implies a superior-subordinate relationship between a function and its subfunctions. The artifacts designed using these languages may not be natural or intuitively obvious to end users, because they do not directly relate to real-world concepts.

OO languages, on the other hand, deal with the notion of an object, which is an encapsulation of procedures and data. These objects directly map onto real-world concepts such as customers, employees, planes, prescriptions, and so on. The notion of an object is consistent in OO analysis, design, and implementation, thus making the OO approach relatively seamless (Richter, 1999). The semantic gap between the problem domain and the solution domain has been reduced because of the ability of OO languages to support higher-level abstractions (e.g., the notion of abstract classes). What then is the problem that confronts us? The problem that lies ahead of us, and is indeed being currently faced by a number of organizations, is how to make a smooth transition from the structured/traditional approach to OO.

And why is this a problem? Table 1 shows some fundamental differences between OO and the traditional approach, and we profess that these differences can be major reasons why the path to OO can be tortuous, steep, and long.

Table 1: Fundamental Differences between OO and the Traditional Approach

Factors

Traditional Development

OO

Abstraction

Procedural or algorithmic

Objects

Decomposition

Top-down functional decomposition that results in a hierarchy of functions.

OO decomposition, that is, objects and their interactions. This decomposition does not imply a hierarchy of objects, but rather a collaboration of objects to accomplish tasks.

Hierarchy

Hierarchy of functions implies a superior-subordinate relationship between a function and its subfunctions immediately below it.

A class hierarchy. The class hierarchy allows one to derive subclasses and specific instances/objects from a class that is at a higher level of abstraction through the process of specialization. The class itself, which may be abstract, is a generalization of subclasses and specific instances

Process model

The waterfall model or some variation of the waterfall model. This model appeared to be appropriate because of the non-evolutionary nature of software development encouraged by the traditional approach.

Boehm’s Spiral Model (1988) or Henderson-Sellers’ and Edwards’ Fountain Model (1990). OO is primarily a prototyping approach that encourages evolutionary software development. Indeed, its basic philosophy is to extend existing systems using predefined classes rather than creating a system from scratch.

These differences have been reiterated in the literature. The first three factors–abstraction, decomposition, and hierarchy–are extremely important because one’s perceptual world dictates how one uses these factors. OO entails a change in perceptual world, and such a change does not happen in a short time, especially for those who have considerable experience with the traditional approach to software development. Further, OO not only subsumes concepts used in the traditional approach but also has its own vocabulary of concepts (e.g., polymorphism, encapsulation, dynamic binding, inheritance, etc.). The faithful representation of reality in a software (implementation) model depends on how the problem is modeled during analysis and design. Polymorphism, encapsulation, and inheritance are implementation idioms that support the semantics of an OO model. The key, therefore, lies in how well the model is developed during the analysis and design phases of systems development.

The cognitive discontinuity involved in making the transition from the traditional approach to the OO method depends on the extent to which the developer was steeped in the structured paradigm. Studies in cognitive psychology suggest that knowledge structures (called schemas) that are developed over time serve as guides to future actions (Alba & Hasher, 1983; Neisser, 1976). If OO is fundamentally different, as suggested by some authors (e.g., Henderson-Sellers & Constantine, 1991), then the schemas developed through years of experience with the structured approach would make the migration effort even more difficult.

Morris, Speier, and Hoffer (1999) suggest that there may be some transfer of prior knowledge when one moves from process to object modeling. However, what exactly is being transferred is not known. These studies may have some bearing on the ability of our students to grasp OO principles. Our experience is that students with some background in structured techniques find it more difficult to migrate to OO. Having been schooled on functional decomposition, they have considerable difficulty conceptualizing a system in terms of objects and their interactions.

Experiences and Lessons Learned

Most programmers take pride in their ability to learn programming languages. However, all of them would readily admit that some of the languages are very different and require an entirely different way of thinking about solutions to problems. In general, there should be little difficulty for one who knows a procedural language to learn another procedural language. Each language has its peculiarities and may have a few concepts that are alien to other languages. The procedural languages emphasize the three basic programming constructs–sequence, iteration, and selection. Any language that does not adhere to this fundamental structure can be difficult (but not impossible) to learn. Classic examples of these are Lisp and Prolog. It takes some time for one to get used to these languages because they require a different way of thinking (e.g., recursion, backtracking).

The main lesson learned from our experience is that any concept that is different and that requires careful analysis before implementation can make the learning curve steep. When one attempts to teach (or learn) C++, one would typically encounter problems with memory management/pointers, virtual functions, and templates, to name but a few concepts. C++ is a hybrid OO language that may be treated as a superset of C. The student learning C++ does not really see the object-oriented features of C++ until much later in the semester, by which time a functional predominance has already set in. And when the student finally gets into the object-oriented aspects of C++, the amount of information can be overwhelming. The instructor and the student have to go through C++’s implementation of OO concepts, which is daunting given the number of things (classes, constructors/destructors, friends, virtual methods, dynamic binding, reference variables, the this pointer, and many more) one has to learn and remember. For example, to create an abstract class in C++, the student has to use a pure virtual function, which in turn requires an understanding of virtual functions. From a pedagogical standpoint, just the use of the keyword abstract should suffice (as in Java).

In the C++ course, we found that students with some exposure to structured languages such as BASIC, COBOL, and Pascal had fewer problems in grasping the syntax of C++ than those with no prior programming experience. However, it took them longer to understand OO program design. Though it is true that Java and Smalltalk enforce the OO paradigm to some extent, they still do not guarantee a complete understanding of OO. In both these languages, students had no difficulty in creating one class with inheritance but had many problems thinking of the problem domain in terms of classes and their interactions. However, students did much better after they were taught use cases, class diagrams, and sequence diagrams.

In our experience, the following are some of the concepts/rules that enabled students to write better OO programs:

Programming to an abstraction or an interface, and knowing when to use inheritance versus delegation. When a client deals with an interface, it can potentially deal with any class that implements that interface, without having to know the implementation details of the class. This makes the client immune to any changes the class that implements the interface may undergo, so long as the interface itself does not change. Programming to an interface provides run-time flexibility, while inheritance tends to commit relationships at compile time. As Gamma, Helm, Johnson, and Vlissides (1995) rightly point out, this understanding is critical for good OO development.

OO modeling is not data modeling. In OO modeling, behavior and dynamics play a critical part in the modeling effort. Figure 1 shows an example where students typically used the data modeling approach before they learned about roles, delegation, and runtime flexibility. In OO, students should learn to distinguish between "a kind of" and "a role played by" relationships (Coad & Mayfield, 1999).

Figure 1. "A Special kind of" versus "A role of" relationships.

Thinking in terms of polymorphism. In simple terms, two classes that realize the same interface(s) are said to be polymorphic. More formally, polymorphism is "the ability to define a single interface with multiple implementations" (Rational University, 1998). Figure 2 shows an example that is used in Richter (1999). In this example, Lendable would be an abstract class (or the implementation of an interface, if it is Java). The "polymorphic" solution has the added advantage of reducing the coupling of the Rental class. From a programming standpoint, polymorphism eliminates the need to have explicit if or switch statements to choose behaviors based on the type to which an object belongs (Fowler, 1999).

Figure 2. Using polymorphism (cardinalties not shown). Adapted from Richter (1999).

A utility class is typically a class that offers a collection of useful methods (e.g., algorithmic services) that may be useful to a programmer in a variety of applications. Examples of utility classes are Hashtable, Set, Map, Vector, Dictionary, and so on. In Java, these classes would normally be in the java.util package. Never subclass a utility class because:

  1. we have no control over changes made to utility classes and
  2. it weakens encapsulation because subclasses are affected by changes to the superclass. Also, a subclass may be used to get to the protected attributes/methods of the superclass (Coad & Mayfield, 1999).

Figure 3 shows an oft-used example. Here, the class Stack is not "a special kind of" vector, but uses it to accomplish its behavior.

Figure 3. Inheritance versus delegation for utility classes. Adapted from Fowler (1999).

Do not use inheritance when subclass objects transmute to another subclass (Coad & Mayfield, 1999). Figure 1, again, is a good example of this rule. It is possible for a student object to become a faculty object (and vice versa). In fact, it is possible for a person to be both a student and a faculty simultaneously. Delegation is the right way to model this.

Use inheritance when the subclass extends rather than overrides or nullifies the superclass’s methods (Coad & Mayfield, 1999), provided the rules/concepts mentioned above are not violated.

These simple rules helped students understand the OO philosophy of software development much better.

UML and Java: A Useful Combination

The Unified Modeling Language (UML) is a standard that has been adopted by the Object Modeling Group (OMG). UML would be the place to start if one wanted to teach OO principles. It is independent of language but can be very easily mapped to the OO language that is being taught in the classroom. Our experience with the use of use cases, class diagrams, and sequence diagrams (using UML) while teaching Java or C++ is very encouraging. The fundamental idea of constructing a model before coding is enabled through the use of UML. Even a brief introduction to some of the UML diagrams can go a long way in helping students understand how to implement systems in an OO way. One of the problems is that programming books focus almost entirely on the language and do not help students see the relationship between analysis, design, and implementation.

Although there are a number of books on OO, most of them are written for practitioners rather than for students. There is an urgent need for a book that discusses OO principles. Books should also incorporate real-world cases that illustrate how the tenets of OO can be applied to practical problems. The books on C++ should impress on the students the need for conceptualizing and representing the problem in terms of objects and classes before getting into implementation details. The first few chapters in most C++ texts discuss structured programming concepts such as functions, sequence, iteration, and selection. By the time the students get to the chapter on classes, objects, and inheritance, they are already into the structured way of looking at problems–that is, breaking a large problem into smaller functions as in functional decomposition. To some extent, this is a problem with books on Java as well.

Java is a pure OO language that has found favor in the industry. It is particularly attractive because of its support for networking, database connectivity, multithreading, client- and server-side applications, stand-alone and Web applications, component-based computing through Beans, and enterprise computing. In addition to these characteristics, its security and garbage collection capabilities make it an ideal choice for developing robust, reliable, and secure systems. Because of the tremendous strides it has made in the industry, Java is an ideal choice for the classroom. Java has quickly grown into something more than a language, and it is virtually impossible to cover all aspects of it in one or two semesters.

Professors who wish to teach OO principles using Smalltalk may encounter a steep learning curve initially, especially if students are firmly entrenched in the structured paradigm. Our brief experience with Smalltalk shows that it is very different from other languages, and students take a while to understand it.

Programming areas such as networking, database connectivity, distributed computing (e.g., CORBA, RMI), multithreading, and the implementation of design patterns are a lot easier to teach in Java than in C++ or Smalltalk. Design patterns are common, domain-independent solutions to recurring problems. A pattern is a way of solving a problem using a design principle (Richter, 1999). Design patterns allow developers to arrive at the correct design in a shorter time. Java’s built-in interfaces (e.g., observer) make it easy to understand and implement design patterns.

In summary, we think the choice of Java as a programming language coupled with some basic modeling concepts using the UML notation would considerably enhance the scope and effectiveness of teaching OO to students.

Conclusions

We believe OO is the wave of the future and is already the preferred approach to software development in many organizations. However, very little effort has been expended to explain the difficulties involved in teaching OO. This article provides some insights into the pedagogical aspects of OO and also discusses some of the problems that render our training efforts less effective. In particular, we discuss our experiences in teaching and in learning OO languages such as C++ and Java.

Our observations are consistent with the claim that the real paradigm shift is at the thinking level–that is, analysis and design stages of software development (Wang & Watson, 1996). It is imperative that students have a good grasp of fundamental concepts, such as classes, objects, encapsulation, dynamic binding, and inheritance, and how these concepts are to be used in formulating a solution to a problem before they are trained on a programming language. In other words, students should first learn to analyze problems and represent them as collaborating objects before they learn about implementation issues using an OO language. Also, the need to create higher-level abstractions with a view to enhancing reusability has to be impressed on the students. This requires skills not only in analysis but also in synthesis, or the ability to specialize (create subclasses and specific instances from a superclass) and to generalize (obtain more general, abstract classes from subclasses and specific instances).

It is also important for students to understand the role of abstraction, decomposition, and inheritance in OO problem solving. In particular, it is mandatory for students of OO to understand concepts such as design patterns, the difference between inheritance and composition, and so forth.

Meyer’s (1993–2001) idea of an "inverted curriculum" in which he proposes a "progressive opening of black boxes" is worth pursuing. In this approach, Meyer (1993–2001) suggests that students be exposed to reusable components and library classes before they are taught what is inside those classes. In other words, students use these reusable components/classes as black boxes and learn to put together a system in terms of such classes. This would require less coding and more thinking in the initial stages. After the OO way of thinking has been instilled, students will be in a position to appreciate the code inside these black boxes and understand how the black boxes achieve their behaviors.

The language of choice can play an important role in the learning and subsequent use of OO concepts. A quintessential OO language such as Smalltalk enforces the paradigm–that is, it makes the student think in terms of objects and message passing from the outset. The language can influence the way one thinks about a problem (Kuhn, 1970; Whorf, 1956). C++ is a hybrid OO language and presents the following problems:

Myriad concepts must be mastered. This takes time and considerable effort. Memory management alone can be a bit of a challenge for many students.

Too many functional or structured concepts might activate a more structured way of problem solving.

Multithreading, networking with sockets and datagrams, and database connectivity are more difficult to teach in C++ than in Java.

At Central Missouri State University, we chose Java because:

  • It is widely used in industry.
  • It enforces the OO paradigm.
  • It helps us bring together networking, database, and distributed computing concepts with relative ease.
  • We find it easier to teach design patterns and multithreading in Java than in any other language.

References

Alba, J. W., & Hasher, L. (1983). Is memory schematic? Psychological Bulletin, 93, 203–231.

Boehm, B. (1988, May). A spiral model of software development and enhancement. Computer, pp. 61–72.

Coad, P., & Mayfield, M. (1999). Java design: Building better apps & applets. Upper Saddle River, NJ: Yourdon Press.

Fowler, M. (1999). Refactoring—Improving the design of existing code. Reading, MA: Addison-Wesley.

Gamma, E, Helm, R., Johnson, R., & Vlissides, J. (1995). Design patterns: Elements of reusable object-oriented software. Reading, MA: Addison-Wesley.

Henderson-Sellers, B., & Constantine, L. L. (1991). Object-oriented development and functional decomposition. Journal of Object-Oriented Programming, 3(5), 11–17.

Henderson-Sellers, B., & Edwards, M. J. (1990). The object-oriented systems life cycle. Communications of the ACM, 33(9), 142–159.

Korson, T., & McGregor, D. J. (1990). Understanding object-oriented: A unifying paradigm. Communications of the ACM, 33(9), 40–60.

Kuhn, S. T. (1970). The structure of scientific revolutions (2nd ed.). Chicago: University of Chicago Press.

Marion, L., Kay, E., Radding, A., Gilhooly, K., Hefner, K., Cimino, D., Swanson, D., & D’Errico. J. (1996a, May). Real-world object management. Software Magazine, pp. 35–50.

Marion, L., Kay, E., Radding, A., Gilhooly, K., Hefner, K., Cimino, D., Swanson, D., & D’Errico. J. (1996b, August). Real-world object management. Software Magazine, pp. 35–50.

Meyer, B. (1988). Object-oriented software construction. New York: Prentice Hall.

Meyer, B. (1993–2001). Towards an O-O curriculum [Online document]. Goleta, CA: Interactive Software Education. Available: www.eiffel.com/doc/manuals/technology/curriculum/page.html.

Morris, G. M., Speier, C., & Hoffer, A. J. (1999). An examination of procedural and object-oriented systems analysis methods: Does prior experience help or hinder performance? Decision Sciences, 30(1), 107–136.

Neisser, U. (1976). Cognition and reality. San Francisco: W.H. Freeman and Company.

Rational University. (1988). Object oriented analysis and design student manual, Part I. Cupertino, CA: Rational Software.

Richter, C. (1999). Designing flexible object-oriented systems with UML. Indianapolis, IN: Macmillan Technical Publishing.

Wang, J. & Watson, R. (1996, November). Five keys to making your OO project succeed. Object Magazine, pp. 37–41.

Whorf, L. B. (1956). Language, thought, and reality (J. B. Carroll, Ed.). Cambridge, MA: The MIT Press.


Contributors

Sridhar Nerur is an assistant professor of information systems at Central Missouri State University. He received his PhD from the University of Texas at Arlington. Dr. Nerur’s research interests include object-oriented analysis and design, software reuse, design patterns, and software metrics. He has published in the MIS Quarterly and in various conference proceedings.

Sam Ramanujan is currently an associate professor at Central Missouri State University. He received his PhD from the University of Houston. Dr. Ramanujan’s research interests include software engineering, global information systems, and distributed technology. He has published in various conference proceedings and journals such as Omega, Journal of Systems and Software, and Journal of Global Information Systems Management.

Someswar Kesh is an associate professor at Central Missouri State University. He received his PhD from the University of Texas at Arlington. Dr. Kesh has published several journal articles and numerous conference proceedings. His research interests include networking, database design and performance, and distributed computing.

Contact

Sridhar Nerur
Dockery 300
Central Missouri State University
Warrensburg, MO 64093
nerur@cmsu1.cmsu.edu

Copyright © 2002, ISTE (International Society for Technology in Education). All rights reserved.

Customer Service: iste@iste.org   1.800.336.5191   1.541.302.3777 (Int'l)   1.541.302.3778 (fax)
Visit the ISTE Career Center for educational technology jobs, resources, and listings. Copyright 1997-