OOP Evolution – How Properties Became Part of Object-Oriented Programming

object-orientedprogramming-languagesproperties

I've come from a C++ background and am going all out C# in my current job and I've just been reading a lot of Q&A about what's the difference between public fields and properties and all the back and forth in variations and incarnations of this basic question (e.g. this SO post and all the related linked questions). All of those questions are addressed in terms of practical differences that take for granted the existence of a property system but I think it would be good to approach this subject in terms of what the designers of all the languages which decided to support properties in the first place were thinking (check out the list in the Wikipedia article here). How did OOP evolve from C++/Java to extend into what the Wikipedia article interestingly identifies as a middleground between methods and member data:

"That is, properties are intermediate between member code (methods)
and member data (instance variables) of the class, and properties
provide a higher level of encapsulation than public fields."

MSDN adds further background:

"Although properties are technically very similar to methods, they are
quite different in terms of their usage scenarios. They should be seen
as smart fields. They have the calling syntax of fields, and the
flexibility of methods."

I'd like to know how it was arrived at that this intermediate level of encapsulation proved useful for programming in general. I'm assuming this concept was not present at the first incarnation of programming languages that expressed the OOP paradigm.

Best Answer

It's all about Encapsulation and the Uniform Access Principle.

An object should be able to respond to a message by either returning existing data or running a method, but the sender shouldn't be able to tell which is which. Or if you view this from the sender's side: the sender should be able to access existing data or run a method through a uniform interface.

There are several ways to achieve this:

  • get rid of data altogether, just have methods (Newspeak does this)

    • a less radical form of the above: get rid of data in the public interface, i.e. make data always private, in the public interface, only expose methods (Smalltalk, Ruby do this)
  • get rid of methods altogether, just have data (Self does this, "methods" are just Method objects assigned to instance variables, instance variables are looked up with virtual dispatch)

  • make no syntactic or semantic distinction between methods and data (Scala does this, accessing a field is syntactically indistinguishable from calling a method without an argument list (foo.bar), assigning to a field is syntactically indistinguishable from calling a specially named method (foo.bar = baz) is the same as foo.bar_=(baz) i.e. calling a method named foo_=, and read-only values can be overridden or implemented by a method without parameter list (i.e. val foo) in a superclass can be overridden (or an abstract val be implemented) in a subclass with a method def foo)

Java, however, doesn't follow the Uniform Access Principle. In Java, it is possible to distinguish between accessing data and running a method. foo.bar is different from foo.bar(). The reason for this is that fields and methods are semantically and syntactically distinct.

C# tries to fix this by adding properties to the language, basically methods that look like fields. However, method calls still look and feel different from field and property accesses. Fields and properties now have Uniform Access, but methods still don't.

So, this doesn't actually fix the problem: you cannot fix having two different ways to access things by adding a third way to access things! Even if that third way looks like one of the other two ways, you will still have (at least) two different ways. You can only fix it by either getting rid of all the different ways except one or get rid of the differences.

It's perfectly fine to have a language with methods, properties and fields, but all three should have uniform access.