Alan Kay, who coined the phrase object-oriented programming has remarked here and in other places, that object-oriented programming is more about messages than objects. The key is that programs are designed as a set of objects that communicate through messages (in many languages a message is referred to as a polymorphic method call).
In Smalltalk (the language Alan Kay was working on) when a message is sent to an object, the receiver of the object determines how the object will respond. In a class-based language, the typical behaviour is:
- Check if the object has a method matching the message's signature, if so invoke that.
- Otherwise, check (recursively) if any of the object's base classes contains a method matching the method signature. When a class inherits another class, it means that the methods of the base class are available for object's of the derived class, but may be overridden to provide different behaviour.
In all the languages mentioned so far, unlike most mainstream languages such as Java, C++ and C#, any object can implement a message for any message. C++ derived a different (and more restrictive) model from Simula, where a message is defined on a base class and can be overridden by a derived class, but no other classes can respond to the method.
Self demonstrated, by including in images a Smalltalk subsystem, that using the prototype-based model a class-based model can be implemented as a pattern of programming, so in this sense the prototype-based model is more descriptive. The converse would require implementing a new object system from scratch (e.g. a class called PrototypicalObject, with behaviour entirely distinct from normal Smalltalk objects).
At its core, OOP is about objects and messages (method calls), where various objects can implement different responses to the same message. The details of inheritance and delegation can help create those objects, but are simply variants of the standard model.