Part III: Object Pascal

In which we discover that Pascal did not stop evolving in 1970, that objects and classes are a natural extension of records and procedures, and that Object Pascal is a living, modern language with nothing to apologize for.


There is a persistent myth in the programming world that Pascal is a "dead language" — a relic of university computer labs, a language people learned in the 1980s and left behind. This myth is wrong, and Part III is where we bury it.

Object Pascal — the language you will learn in the next six chapters — is a fully modern, statically-typed, object-oriented programming language with classes, inheritance, interfaces, exceptions, generics, and anonymous functions. It compiles to native machine code on Windows, macOS, Linux, iOS, Android, and embedded platforms. It produces executables that start instantly, consume modest memory, and require no runtime or virtual machine. The Free Pascal compiler that powers our work in this textbook supports all of these features and is itself written in Pascal — a compiler bootstrapping its own language, a feat of engineering that has continued unbroken since the 1990s.

Delphi, the commercial Object Pascal environment, powers mission-critical software in healthcare, logistics, banking, and government across the world. Lazarus, its open-source counterpart, provides a RAD (Rapid Application Development) experience that rivals anything on the market. When you write Object Pascal, you are not writing a museum piece. You are writing in a language that ships production software every single day.

Part III teaches you this language.

The Transition

If you have completed Parts I and II, you already know more Object Pascal than you realize. A record is a class waiting to happen. A procedure that takes a record as its first parameter is a method that has not yet been invited inside. The var parameter mechanism is the same pass-by-reference that powers method calls on object instances. Pascal's strict type system, which you have been living with for fifteen chapters, becomes the foundation for polymorphism: because Pascal knows the type of every variable at compile time, it can also know when a subclass can safely substitute for a parent class.

The transition from procedural to object-oriented thinking is one of the most significant conceptual shifts in programming. Part III handles it carefully. We do not abandon everything you have learned. We extend it.

What These Chapters Cover

Chapter 16 introduces classes and objects — the fundamental building blocks of Object Pascal. You will learn how a class differs from a record (hint: it lives on the heap and supports methods, constructors, destructors, and access modifiers). You will write your first class, create instances with Create, free them with Free, and understand the Self keyword. PennyWise undergoes its first object-oriented redesign: the TExpense record becomes a TExpense class, and the flat procedures that operated on expenses become methods that belong to the class itself. Rosa notices that the code is shorter after the redesign — not longer — because the data and the operations that act on it are finally in the same place.

Chapter 17 covers inheritance and polymorphism. You will build class hierarchies, override methods, use the virtual and override keywords, and understand why the is and as operators exist. PennyWise introduces TRecurringExpense as a subclass of TExpense, and Tomás discovers that his monthly Spotify subscription and his weekly grocery run can now be modeled differently while still fitting into the same transaction list. Crypts of Pascalia benefits here too: TItem, TWeapon, TPotion, and TKey form a clean inheritance tree.

Chapter 18 introduces interfaces — Pascal's answer to the limitations of single inheritance. Interfaces define contracts without implementation, enabling the kind of flexible, decoupled architecture that professional software demands. PennyWise gains an IExportable interface, allowing any object that implements it to be written to CSV, JSON, or a printed report — without knowing or caring about the object's concrete class.

Chapter 19 covers exception handling: try-except, try-finally, raising exceptions, and defining custom exception classes. This is the chapter that transforms your programs from fragile demonstrations into robust applications. Every file operation, every user input parse, every network call can fail — and exceptions give you a structured, readable way to handle failure without littering your code with error-checking if statements. PennyWise wraps its file I/O in exception handlers, and for the first time, a corrupted save file produces a helpful error message instead of a crash.

Chapter 20 introduces generics — parameterized types that let you write code once and use it with any type. You will build a generic TList<T>, understand type constraints, and see how generics eliminate the need for unsafe typecasting. PennyWise replaces its hand-rolled linked list with a generic TObjectList<TExpense>, and the code becomes both safer and cleaner.

Chapter 21 surveys advanced Object Pascal features: operator overloading, class helpers, advanced RTTI (Run-Time Type Information), anonymous methods, and functional-style programming. This chapter shows you the ceiling of the language — and demonstrates that the ceiling is very high indeed.

The PennyWise Redesign

The PennyWise that emerges from Part III is architecturally different from the one that entered. Where the Part II version was a procedural program with good data structures, the Part III version is a properly designed object-oriented application:

  • TExpense is a class with properties, validation logic, and formatting methods.
  • TBudget aggregates expenses, enforces limits, and raises events when a category is overspent.
  • TExpenseRepository handles all file I/O through an interface, making it possible to swap file-based storage for database storage later without changing a line of business logic.
  • Exception handling means that Rosa's PennyWise no longer crashes when she accidentally deletes her data file. It notices, tells her what happened, and offers to start fresh.

This is not redesign for the sake of redesign. It is redesign because the program has grown to the point where procedural organization creates friction — where adding a new feature means modifying five procedures in three different units, and where a bug in one place can silently corrupt data in another. Object-oriented design does not eliminate complexity. It manages complexity, by giving each piece of the program a clear identity, a clear responsibility, and a clear boundary.

A Living Language

One of the recurring themes of this textbook is that Pascal is not a historical curiosity. It is a living, evolving language with an active community, modern tooling, and capabilities that rival — and in some cases exceed — languages with far more marketing behind them.

Part III makes this argument concretely. Generics, interfaces, exception handling, anonymous methods — these are features associated with "modern" languages like C#, Java, and Swift. Object Pascal has had all of them for years, in some cases decades. The language that Wirth designed to teach clear thinking has grown, under the stewardship of Borland, Embarcadero, and the Free Pascal community, into a language that can build anything.

The next six chapters prove it. Let us begin the transformation.

Chapters in This Part