- In the Beginning, There Were Bits
- Structured Programming
- The Next Level Up: Functions and Procedures
- Classes: Beyond Structured Programming
- Conclusion: Abstraction Costs and Benefits
Classes: Beyond Structured Programming
Structured programming and functions neatly solve some of the problems of maintenance by limiting the amount of code you have to look at in order to understand any given line. There's still one way that far-off pieces of code can affect a particular line of code, however: state.
The sort example given earlier sorts only integers, which is not a particularly interesting job. Why would you ever want to sort just a list of numbers? More likely, you want to be able to sort a list of objects of some kind, based on an integer key. Or, more generally, you'd like to be able to sort on any key, as long as you can reliably compare any two objects.
Even before object-oriented programming, there were ways to group chunks of data into functional units. In C, these units are called structs. However, structs don't have any reliable way to compare them. You need some level of abstraction a little higher than provided by structs that allows you to tell which of two structs should come first. The abstraction of grouping code and its data structures is called object-oriented programming. The clump of code and data definitions is called a class in most programming languages.
C++ is an object-oriented language. It provides a higher level of abstraction than C does. In general, higher levels of abstraction come at a performance penalty, and many people criticize C++ for its performance cost relative to C++.
Java aims for an even higher level of abstraction than C++ by abstracting away access to locations in memory. Though not the first language to do so (Lisp and Basic leap readily to mind, among general-purpose programming languages), it probably has the highest market penetration.
And that level of abstraction also costs performance most of the time. Not always, of course. An advantage to abstraction is that the intermediary translators are allowed to make any optimizations they want, as long as they don't violate the contracts. The larger the program, the harder it is for you to perform all the optimizations yourself and still make the schedule. The longer a language has been around, the more tricks the compiler writers learn for optimization. Increasingly, languages at higher levels of granularity perform faster than those at lower levels. There's no way you could write a large program for a Pentium processor and make it as efficient as the same program written in C; the pipeline stalls would suck up all of your performance gains (even if you knew what they were).