| Classes by themselves are just another name for abstract data types, so just being able to define classes, i.e. structures together with methods that manipulate their members is not enough to qualify as OOP. Abstract data types have a field of applicability far larger than OOP. OOP has 2 main features, which have first appeared in SIMULA-67: inheritance and virtual functions. I agree with the following definition for OOP as as a special kind of programming with abstract data types: "There are two features that distinguish an object-oriented language from one based on abstract data types: polymorphism caused by late-binding of procedure calls and inheritance. Polymorphism leads to the idea of using the set of messages that an object understands as its type, and inheritance leads to the idea of an abstract class. Both are important." (Ralph E. Johnson & Brian Foote, Journal of Object-Oriented Programming, June/July 1988, Volume 1, Number 2, pages 22-35) When virtual functions are not used, the operations can be considered as belonging to the type (a.k.a. class), not to the objects, which corresponds to the jargon used by programming with abstract data types. When virtual functions are used, the operations are considered as belonging to the objects, not to the class, as each object may have a different implementation of a given method. This corresponds with the point of view of OOP. I have used the SIMULA/C++ term of "virtual functions", but in some OOP languages all functions are of the kind named "virtual" in SIMULA, so the "virtual" term is not used. |
Once you separate type hierarchy and behavior, you get a much more flexible system. That's what newer languages (Rust, Swift and co.) do. I think the reason why "classes" are so popular has to do with compiler technology — type hierarchies can implement polymorphism very efficiently via vtables, and folks jumped on the opportunity of having high-level abstractions with high performance (instead of doing expensive lookups associated with earlier per-instance polymorphism). But as the compiler tech and understanding of programming language theory have progressed, these limitations are not necessary for good performance anymore, in fact, they become limiting.