In Object Oriented Programming, a class is a name for the basic unit of code, also called a module. Objects can be instantiated from a class, and the class definition provides "rules" of how that object will behave at runtime, and what can be done to it.

Encapsulation is key to the idea of classes, and OOP. Ideally, classes should be a representation of some object in the real world that we can directly relate to - for instance, a Rectangle class should be able to define its position, size - everything about it we would expect to know in the real world - and allow us to manipulate it as we would in the real world.

Classes contain two main things to allow them to do this: data members and member functions. The data members are the bits of memory that store the information a class needs to do its job, and the member functions are the actual operations that provide the functionality of the class.

Objects communicate with each other by calling each other's member functions (also known as "sending a message" to that object). It is considered very bad form to direct manipulate another objects' data members, so classes should provide what are commonly known as "Get/Set" functions (because, say, for a data member called Size, they will usually be called GetSize() and SetSize()) to manipulate the data. This is very important for one main reason: consistency of state.

If an object is allowed to directly manipulate another object's data members, then its member functions essentially "lose track" of these data members. Imagine a Rectangle class that only allows itself to be 200 pixels wide. If another object sets its width to 250 pixels, it is likely the class will start to behave incorrectly. The whole idea of OOP is that an object gets to decide for itself how things are done, and that every other class in the system doesn't really need to know how these things are done. If objects are going to start messing around with each other's internal data, this whole system falls down.

Now for a little programmerese (as if the above wasn't enough!) Classes, in general, can either exist in solution space or implementation space. Remember how I said a class represents some concept in the real world? That's a class in solution space - it represents an object that exists as part of our solution, such as letters, words and fonts in a word processor. These types of classes are often referred to as abstract types (but this is also a more general term, so don't get too wrapped up with it).

Classes in implementation space are classes representing objects that exist in the implementation of a program and have a relevence to it, but aren't immediately obvious as part of the solution. These are often concrete types. As an example, in implementing a word processor, I might use a linked list or a deque to store sentences, but this isn't immediately obvious from problem. Linked lists are needed to implement the program, but they cannot be directly mapped to an object or concept in the problem.

One of the main tasks of Object Oriented Design is what's called "Finding the classes", which is to say, deciding what classes should be used in a system to represent and build the solution.