What are some of the other languages that interpret "private" as never exposing the existence of that field to a public consumer? Most languages I've used don't expose the _value_ of the field...
What are some of the other languages that interpret "private" as never exposing the existence of that field to a public consumer? Most languages I've used don't expose the _value_ of the field...
See [0] for some info straight from the proposal, but the gist is doing it this way makes it so that you never have to worry about name collisions for private fields. Subclassing, superclassing, and object "monkey patching" all can continue to work as-is with no changes, and none of them have to worry about the existence of private fields complicating implementations, and the classes with private fields can feel free to change and rename them as much as possible, even within patch versions of libraries, since they cannot impact any code outside of the class under any circumstances. That's a pretty powerful guarantee to give which GREATLY simplifies working with them.
If I want to extend the react component class, I don't need to worry that my `#component` private field is going to break if an update to the react component class adds their own `#component` field, or if a user of my library tries to do something like this:
const fancyObj = new FancyObj()
fancyObj.tag = Symbol('tag')
Which I'll admit to having used in some cases where I want to tag a bunch of otherwise identical objects which will be thrown into an array and then be able to easily pluck out the ones I tagged later. Without true encapsulation, that code above would break if they changed the private interface to use the `.tag` field internally, and I would have no idea because it is consitered a private interface and wouldn't need to be documented or maintained across versions.[0] https://github.com/tc39/proposal-class-fields/blob/master/PR...
There is nothing addressed here that can't be solved with composition. This seems like an odd step for an aspiring functional language to take...
Some of that is pushing it in a functional direction, some in a "classic OOP" direction.
Much like classes in the first place, this is a feature added to the language to stop the proliferation of stop-gap solutions and standardize on one implementation for most.
Sure, I won't be using this feature, just like I won't be using classes at all in most cases (React components being one exception), but many will, and if this isn't added, they will continue trying to solve problems with solutions which are more complicated, slower, and buggier than this. All the talk about how it's not the "right" solution doesn't matter.
To use an over-the-top metaphor: People are jumping out of planes, and you aren't going to stop them, so the very least you can do is give them a well tested parachute and a map of where to safely land.
class Base {
private int field;
Base() {
this.field = 1;
}
void baseMethod() {
System.out.println("Base.field = " + field);
}
}
class Derived extends Base {
private int field;
Derived() {
this.field = 2;
}
void derivedMethod() {
System.out.println("Derived.field = " + field);
}
}
public static void main(String[ ] args) {
Derived d = new Derived();
d.baseMethod();
d.derivedMethod();
}
It prints: Base.field = 1
Derived.field = 2 class Base:
def __init__(self):
self.__field = 1
def baseMethod(self):
print("baseMethod " + str(self.__field))
class Derived(Base):
def __init__(self):
super().__init__()
self.__field = 2
def derivedMethod(self):
print("barMethod " + str(self.__field))
d = Derived()
d.baseMethod()
d.derivedMethod()
And it prints: baseMethod 1
barMethod 2
Ruby doesn't really have fields that are private to subclasses, but Ruby also embraces monkey-patching, so that's not entirely surprising.