Object-oriented
|
The old language Pascal was said to be actively hostile to OOP, although there were OOP extensions of Pascal: Classcal early on, and later Borland's Delphei. But it is not possible to do OOP in standard Pascal. On the other hand, the C language enables OOP -- one can do a good job of simulating OOP within standard C, and this is one reason (of several) for the success of C. Of course, C++ and Java do a good job of implementing OOP, within the constraint of efficiency at run-time.
The language Smalltalk is the prototypical OOP language, where absolutely everything is an object, and instead of methods, objects communicate with one another at run-time by sending messages to one another. The language Objective-C incorporated these Smalltalk features into an extension of C. Thus both Smalltalk and Objective-C do more at run-time and are inherently less efficient than C or C++.
Instead, C uses a separate file to give many of the features of OOP to the language. This is part of the reason I am starting before introducing C structs.
In fairness, I should also say that there is another way to simulate OOP in C: use a struct to hold all the different data members of an object. This is the approach taken in some parts of the Weiss textbook. This is an awkward method, where the data members are partly inaccessible just because it is so hard to get to them. I don't support this messy method, although it does allow multiple copies of an object to be created.
Item or Activity | "Faked" OOP in C | OOP in C++/Java |
---|---|---|
The object itself | A separate file | A class |
Private date members | Ordinary data declarations | Data declared private |
Public date members | Data declared extern | Data declared public |
Private member function | Function declared static | Function declared private |
Public member function | Ordinary function definition | Function declared public |
Creating objects | Only one instance possible (separate file for each instance) |
Any number of instances |
Initialization | Initializing code (may need separate call) |
Constructor |
Connections between objects |
Header files | C++: Header files Java: None needed |
Each of the implementations uses separate files for the class ("class" in C). The C++ implementation is very similar to the Java one, except that C++ needs a header file and a destructor. Let's focus, however on the C implementation:
C Stack: Header |
---|
/* stack.h: header file */ void push(char); char pop(); int empty(); int full(); |
C Stack: Implementation |
---|
/* stack.c: stack implem */ #include "stack.h" #define MAXSTACK 10 #define EMPTYSTACK -1 int top = EMPTYSTACK; char items[MAXSTACK]; void push(char c) { items[++top] = c; } char pop() { return items[top--]; } int full() { return top+1 == MAXSTACK; } int empty() { return top == EMPTYSTACK; } |
Notice above that the prototype header file is included, using #include "stack.h". All initialization is performed just with assignment statements, but in general one might need a public initialization function that would have to be called before using the object.
C Stack: Use |
---|
/* stackmain.c: use stack */ #include <stdio.h> #include "stack.h" int main() { char ch; while ((ch = getchar()) != '\n') if (!full()) push(ch); while (!empty()) printf("%c", pop()); printf("\n"); } |
Other kinds of C++ and Java classes can't use separate files for their implementation in C: as examples consider situations where multiple instantiations are necessary, such as the node of a binary tree.
As explained on the above listing, the C++ and Java programs in one file have most of the properties and functionality that they had in a separate file -- just that the Stack class can't be used from the outside, but there can be multiple instances of multiple sizes. The C program, however, has suffered a great deal from being implemented in a single file. Now there is no emcapsulation of the stack implementation. The data members are not hidden and are directly accessible from anywhere in the file. It would be possible for code to change stack variables and put the stack into an inconsistent state, something which is very bad.