Organization is always critical to writing good code. We have already discussed modularization in the form of subroutines and units which helps in organization. One of the most powerful concepts in modern programming is object-oriented programming. Object-oriented programming (OOP) is a programming paradigm that uses classes and objects (the latter of which are instances of classes). A class is similar to a record in that both have data fields. The first major difference is that classes also have methods, or subroutines that are closely associated and grouped with the class and its fields. Just as with records, once we define a class we have to create variable instances. In this case these instances are known as objects. Consider the following class definition:
type
  TRectangle = class(TObject)
    X,Y : Real;
    Width,Height : Real;
  end;
There are several things to point out about this code. First, note that the field definitions are identical to record field definitions. Second, note the class(TObject) part of the definition. One of the most useful features about classes is that they can be organized into hierarchies based on inheritance. All classes in Object Pascal descend from the ancestor class TObject. Even if we had omitted the (TObject) part of the definition, the class TRectangle would have descended automatically from TObject. To begin to illustrate the utility of this method, let's modify our definition:
type
  TShape = class(TObject)
    X,Y : Double;
  end;

type
  TRectangle = class(TShape)
    Width,Height : Double;
  end;

type
  TCircle = class(TShape)
    Radius : Double;
  end;
Now we have defined the class TShape. It's descendants are TRectangle and TCircle. Because TRectangle and TCircle descend from TShape, the fields X and Y are automatically inherited . Besides making the definitions easier to write (because we don't have to repeat X and Y for every TShape), we will later see how this makes actual coding much easier as well.

Now that we have a few classes, let's create instances of those classes (aka objects):
var
  Rect : TRectangle;
begin
  Rect := TRectangle.Create;
  Rect.Destroy;
end.
The code above illustrates a very important point about how objects are created. When we were dealing with records, simply declaring a variable with a record type was enough to create the instance. For objects, the declaration Rect : TRectangle only creates a variable that will contain a reference to an actual object. The object itself is created when we call TRectangle.Create which is a constructor. A constructor is a subroutine much like a function except that it always returns the same thing: a pointer to the object created. In Object Pascal, a pointer is a reference to the memory location where something is stored. This pointer can then be stored in a variable (in this case Rect). Finally, when we are done with an object we often call its destructor which frees up any memory associated with the object. In Object Pascal, calling the destructor is not required because the so-called garbage collector cleans up unused objects in the long-term, but calling it does result in more memory-efficient code in the short-term.

Let's return to the idea of a pointer to an object. Remember that when passing instances of records to procedures and functions we had to pass them by reference:
type
  TRectangle = record
    X,Y : Double;
    Width,Height : Double;
  end;

procedure DrawShape(const Shape : TRectangle);
begin
  with Shape do
    FillRect(X-Width/2,Y-Height/2,X+Width/2,Y+Height/2);
end;
For objects (i.e., instances of classes) contained in variables we do not have to do this because the value in the variable is a pointer which is by definition a memory reference:
type
  TRectangle = class(TShape)
    X,Y : Double;
    Width,Height : Double;
  end;

function Area(Shape : TRectangle) : Double;
begin
  with Shape do
    Result := Width*Height;
end;
One important caveat, however, is that any change made to an object inside a subroutine is always reflected in the object even after the subroutine exits since it is always a reference.

In the code above we declared the function Area and passed a reference of the class to this function as an argument. A better way of achieving the same thing is to make Area a method of the class TRectangle:
type
  TRectangle = class(TShape)
    Width,Height : Double;
    function Area : Double;
  end;

function TRectangle.Area : Double;
begin
  Result := Width*Height;
end;
When we define a method we have to declare its kind (procedure or function) and argument list first in the class definition and then again when we want to implement it as shown above. We always prefix the name of a method with the name of the class (as in TRectangle.Area). Inside the begin-end part of the procedure, notice that we do not have to use any with statements. This is because the TRectangle part in the name TRectangle.Area makes all of the fields of TRectangle visible to the subroutine.

Outside of the class definition, the visibility of fields and methods can be public, protected, or private. These directives are known as visibility directives, and they are demonstrated in the following code:
type
  TRectangle = class(TShape)
  // These fields/methods are public by default
    PublicField1 : Integer;
    PublicField2 : Integer;
    procedure PublicMethod1;

  // These fields/methods are public
  public
    PublicField3 : Integer;
    PublicField4 : Integer;
    procedure PublicMethod2;

  // These fields/methods are private
  private
    PrivateField1 : Integer;
    procedure PrivateMethod1;

  // These fields/methods are protected
  protected
    ProtectedField1 : Integer;
    procedure ProtectedMethod1;
  end;
The public directive is the least restrictive and means that fields/methods are visible anywhere a class is visible. The private directive is the most restrictive and means that fields/methods are only visible inside the source file in which the class is defined. The protected directive is somewhere in between public and private. Proctected fields/methods are visible to any other class defined in the same source file as the class to which they belong as well as any descendent class regardless of the source file.

At this point, you may be wondering why we would want to restrict access to fields/methods. The reason is encapsulation. We can seal off code in parts of the class from other code in the program in order to prevent bugs that might arise from misuse of data contained in a class. While just placing fields and methods in a class is encapsulating them, specifying their visibility adds an additional layer to restrict access to certain data or behaviors that the class might implement.

We will explore many other aspects of classes throughout this chapter but for now you should simply keep in mind that classes are a way of organizing code and encapsulating functionality so a program can grow in complexity without declining in maintainability.