The transition from one programming style to another is often a very difficult one. After reading [7], which claims that the proposal in [8] of adapting the original procedural version of the "Hello, world" program into an object-oriented version is harmful, we are inspired to make at least three remarks: that there is a need among educators to address ways to differentiate between OO programming and OO programming languages; that confusion about the fundamentals of OOP is still prevalent among educators, and this confusion is being instituted by current textbooks; and that educators should exert more influence on the quality of textbooks. Here, we address some of the issues raised by [7] and [8]; to preserve the context, we reproduce the sample code used in [8] and considered harmful by [7] in the figure appearing here.
Although there is no widely agreed-upon formal definition for the term OOP, we can safely and reasonably assert, based on current research (for example, [1]), that part1 of the fundamentals of OOP is the following:
Typically, an object contains both data components (fields) and operation components (methods), and the operation methods are usually defined/performed over the data fields. Nevertheless, an object need not have both operation methods and data fields present to be legitimate. That is, an object may be formed merely of data fields or operation methods. In the former case, the resulting object "degenerates" primarily to a Pascal-style record, where only primitive type or aggregate type data items are allowed to be record members. In the latter case, the resulting object (still) degenerates primarily to a ML-style record, where functions are permitted to be record members.2 Indeed, objects are a general concept that includes records as special instances. Pedagogically, introducing object concepts to first-time students would require us to start from simple objects and gradually move toward more complicated ones. So what is the simplest object? The empty object, of course. Although its usefulness is not evident, the empty object does provide the starting point of an inductive strategy for constructing objects: an object of one component is extended from the empty object; an object of n components is extended from a (n-1)-component object, for any n>1, n N.
Classes are not an essential part of the fundamentals of OOP. Due to the influence of C++ and Java, most students, some programmers, and some instructors think we must have classes in order to program in an OO style; it is not the case. In fact, there are two types of OO languages representing two different approaches to the OOP paradigm: class-based languages (for example, C++ and Java), with which we are familiar, and prototype-based languages (for example, Self [6], Kevo [5], and Omega [2]), with which we may not be familiar. In the former, classes are used as the manufacturer as well as the type of objects.3 In the latter, no class notion is needed; objects can be created either from scratch or by inheritance (from another object), and the languages are much cleaner.
Consider the code shown in the figure here. Overall, it does a good job in conveying the basic ideas of OOP. Namely, it shows that an object (myHello
) must be created first in order to initiate a computation; and the computation is accomplished by invoking a method of this object. Since the code is written in Java, classes are inevitable. Unfortunately, the code itself is not flawless. The loophole of the code in the figure is that the method printHello
in class HelloWorld
should be defined as an "object method"4 rather than a "class method"5 (that is, remove the keyword static) because it is supposed to be invoked through the object myHello
. Furthermore, doing so will force method printHello
to be (only) invoked through an object and eliminate the chance for it to be invoked through a class (as in [7], and described later).
Java offers both class (static) methods and object (non-static) methods. On one hand, this mechanism increases the flexibility of the language; on the other hand, however, it introduces non-essential and unsound constructs confusing to most of us. While an object method, as expected, can only be invoked through messages sent to the object, a class method can be invoked through both messages sent to the class and messages sent to objects of that class (see the table here). This is so semantically confusing that most "introduction-to-OOP-using-Java" textbooks are vague about this point, and some of them even make plainly wrong statements stating that class methods cannot be invoked through objects (see the example in [4] at the bottom of page 101). We can see here the entanglement of OOP with language idiosyncrasies and the necessity of focusing on essential concepts of OOP and distinguishing them from specific OO languages.
The major points made by [7] include:
HelloWorld
in the figure has neither data members nor instance methods (object methods). (So the class is useless.)printHello
in the figure is called bypublic class UseHello
{ public static void main(String args[])
{ HelloWorld.printHello(); }
}
UseHello
in the figure lacks any cohesive purpose.We disagree with each one of the preceding points as put forth by [7]. For point 1, it contradicts clearly the sample code. As shown, the figure reveals the basic functionality of OOP by creating an object and sending a message to this object to accomplish the computation. On the other hand, the original pure procedural version of "Hello, world" is just that and has nothing to do with object-orientation.
Due to the influence of C++ and Java, most students, some programmers, and some instructors think we must have classes in order to program in an OO style; it is not the case.
For point 2, we know, by our earlier elaboration on OOP, that an object does not have to have any data members. It is perfectly fine for the class HelloWorld
to contain just one method (printHello
). Being trivial does not take away the essence of the example. Unfortunately, as we have pointed out, the method printHello
should be defined as an object (instance) method, not a class method, to be more appropriate.
For point 3, this would be a shorter working Java code (if and only if we keep the keyword static
for method printHello
in the figure). However, sending messages to classes is merely a Java peculiarity; it is not an indispensable part of OOP. Even though Java is considered an OOP language, not every Java feature is an OOP construct. This point highlights the recurrent tensions between methodologies and languages.
For point 4, the purpose of the class UseHello
is obvious: show how an object of HelloWorld
can be created and how a message can be sent to this object to perform a computation. Of course, both HelloWorld
and UseHello
are toy examples. They are intended to be the very first and the simplest examples for showing OOP essentials to beginners. Nothing more should be expected of them.
We conclude with the following remarks:
1. Abadi, M. and Cardelli, L. A Theory of Objects. Springer-Verlag, New York, 1996.
2. Blaschek, G. Object-Oriented Programming with Prototypes. Springer-Verlag, 1994.
3. Cook, W., Hill, W., and Canning, P. Inheritance is not subtyping. In Proceedings of the 17th Annual ACM Symposium on Principles of Programming Languages, 1990.
4. Holmes, B. and Joyce, D. Object-Oriented Programming with Java. Jones and Bartlett, Sudbury, MA, Second ed., 2001.
5. Taivalsaari, A. Kevo: A Prototype-based Object-Oriented Language Based on Concatenation and Module Operations. Technical Report LACIR 92-02, University of Victoria, B.C., Canada, 1992.
6. Ungar, D. and Smith, R.B. Self: The power of simplicity. In Proceedings of OOPSLA'87, 1987.
7. Weisert, C. Pseudo object-oriented programming considered harmful. ACM SIGPLAN Notices 37, 4 (2002).
8. Westfall, R. Hello, world considered harmful. Commun. ACM 44, 10 (Oct. 2001), 129130.
1Other important aspects of OOP, such as inheritance and subtyping, are not addressed here.
2In both cases, to be precise, we need to ensure there are no interdependencies among the components in an object before we can call it a record.
3Using classes as object types actually contributes to the issue of the confusion between subclassing (inheritance) and subtyping [3].
©2003 ACM 0002-0782/03/1000 $5.00
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee.
The Digital Library is published by the Association for Computing Machinery. Copyright © 2003 ACM, Inc.
No entries found