We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, I'm new to processing, and am using it primarily because we have adopted it at our school as the language to use with our AP Computer Principles course. Some of the "sandboxed from java" aspects of it have me a little frustrated. In particular, I cannot manage to disallow direct access to member fields from outside the class to force the use of getter method.
I can accept that in processing all member fields in a class are accessible by default - probably package-private - as they are in Java. But I can't seem to change this. The use of "private" before a field declaration is NOT disallowing direct access to the attribute from outside the class. Why is private not working? For example, in the code below, the miles instance variable can be directly accessed (and even set!) after the object is instantiated despite the use of the private keyword in its declaration.
In a separate "tab" to define a class
class Car {
String make;
private int miles;
Car(String m, int d) {
make = m;
miles = d;
}
void drive(int dist) {
miles += dist;
}
}
Then, in a sketch
void setup() {
Car herbie = new Car("Ford", 5);
print(herbie.miles + "\n");
herbie.miles = 7;
print(herbie.miles + "\n");
herbie.drive(43);
print(herbie.miles +"\n");
I thought that maybe in the example above it was owing to the fact that processing does something funny with the classes defined in tabs associated with a given sketch to allow direct access from within the setup() function. But this disrespect for "private" is true even if I construct another class that instantiates a Car object within its own constructor (or in some other function for that matter.) and then accesses miles directly. In that case I am clearly accessing the car's member field from a completely different class.
Isn't there a way to protect instance variables in processing?
Answers
Also private sucks. I think protected is way better in most cases unless you have the deal with security.
public
unless explicitly declared otherwise.color
primitive type, autopublic
declaration, autof
suffixing for all fraction literals, etc., won't happen for ".java" files. (:|protected
is the most balanced restrictive access level available in Java. ~O)private
and its cousin "default package" access levels are very much too restrictive.The OP is doing a 'AP Computer Principles' course so is different from many of the people on this forum who are not interested in applying the principles of object orientation.
Most people using Processing don't care one little bit about OO principles and only become aware of the usefulness of creating their own classes when developing larger apps with more complex data structures. These people are only interested in the class syntax and are quite happy to accept Processing default implementation of
public
even though in many ways this goes against OO principles. But that's alright because Processing was designed to do just that.If you are interested in create 'quality' software using an OO language then the choice of modifier should be chosen based on OO principles rather than convenience or personal preference
I do agree that the default level of package-private is too restrictive because it is based on the physical storage of the class files rather than on their 'logical' connectedness. C++ overcomes this with friend classes.
When designing a class then the access modifiers should be chosen based on good OO design principles, if that means it should be
private
then so be it. Most OO programmers, including myself, would agree to useprotected
instead ofprivate
unless there is an absolute need to make itprivate
.I just wanted to add that many folks wouldn't consider access level an OOP principle! 8-X
Many important languages based on objects don't have any built-in access levels at all!
Those include JavaScript, Lua and faculty's new darling Python for example! O:-)
IMO, Java isn't an ideal language for introduction to programming b/c, besides all its ugly boilerplate gang:
package
,class
,public static main(String[] args) {}
, etc. just to get started w/ some "Hello World" program, teachers also feel "obliged" to force students to learn & use access levels in all places for everything! :-@And don't get me started w/ all the "getters" & "setters" stuff for each single field every time they create some class! :-\"
That's why many faculties are preferring languages like Python for their base courses nowadays!
However, I find Processing framework + Java even more friendly than Python, b/c it removes the need of worrying about access levels. And consequently those getter & setter boilerplates along!
And at the same time, "Java Mode" doesn't have those extra
self
"warts" present in all Python's methods! It's much more clean & high performance! \m/Also Processing + JS, be it p5*js or pjs, are getting more attention too.
See this very recent example: http://forum.processing.org/two/discussion/10960/new-mobile-friendly-online-editor-for-processing-sketch-world
http://sketch.world/app/#/
And don't forget there are Python & Ruby modes for Processing as well! :P
The OO principle is called encapsulation and using access level modifiers is one means of achieving it.
Indeed access level is an important aspect of encapsulation.
However, even w/o access levels, the simple fact that members belong to a specific
class
makes them encapsulated already! :PFrom: http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Encapsulation is the packing of data and functions into a single component.
In programming languages, encapsulation is used to refer to one of two related but distinct notions,
and sometimes to the combination thereof:
... thus, information hiding is defined as a separate notion by those who prefer the second definition.
In short, Java's
class
keyword already means a construct that bundles data w/ their methods! :-BAccess levels are just the cherry at the top! :D
@GoToLoop said:
We're probably straying into semantics and technicalities here (and I don't have a computer science background so my theory is probably lacking!) but JavaScript does of course have a form of 'encapsulation': variables declared at function level (with
var
) are private to that function and properties can also be added directly to objects to limit their scope. Anyone wanting to build complex web apps would be very foolish to declare all their variables in the global scope ;)Edit: I guess the point I'm making is that whether it's built into the language directly or not, it's both possible and desirable, if not essential, to implement some form of encapsulation in JS.
I think Processing has the balance about right though: you're unlikely to be building applications at a scale where the lack of private members becomes an issue; and you can always take the approach some have taken with JS and rely on a naming convention to flag properties and methods that should not be accessed outside the owning 'class'.
Just to conclude and make sure everything is clear:
private
and the other access levels in any way.P.S.: Although very limited in Java, nested classes & anonymous instantiations are able to access members from their enclosing class due to closures, just like in JS! :ar!
OP here. Thanks everyone. All good points. Super clear now. I must say that in the past we have used Ruby as our language for intro programming with great success. Graphics were fine using FOX (FXRuby) by the end of the course. But the College Board's new AP Computer Principals course lends itself to a statically typed language, and one that allows for almost immediate processing of a wide variety of data (image, audio etc.) Processing sort of emerged as a good option for our population. Alas, nothing will be perfect.
"Also private sucks. I think protected is way better in most cases unless you have the deal with security."
Don't tell that to "real" Java programmers, ie. those coding Java for a living in teams and enterprises... :-)
It is not only about security, though.
Imagine a Processing user coding a library. He exposes a carefully crafted API, but has to create lot of intermediary fields and methods, to be used only in the internal algorithms of his library.
If these fields and methods are not private, people can start to use them, even if they are not officially documented. A bit like we do with dataFile() in Processing... :-)
But then, if, for some reason, the library author decide to change dramatically the algorithm, while keeping the same official API. It has to remove or rename existing fields and method. But then comes a dilemma: either he just breaks lot of sketches that started to use the non-official exposed members; or he has to maintain these obsolete members.
In short: non-private members increases the API surface, thus the burden of maintaining the software.
Personally, I rarely use
protected
visibility, but more often the package-private (default, no modifier) one: one has to put a class in the same package to access them, which is rarely worth the hassle, yet it allows companion classes to access these members.That's why I reiterate that
protected
is the best access level.When we access anything not specified in an official library's API, we do it consciously at own risk by inheriting the class.
Therefore we can change the original functionality immediately w/o needing to ask the author to modify its library 1st.
Or while awaiting the author to accept the modification request.
If the author modifies anything later, it's our problem if we relied on an unofficial API anyways.
But at least we can do it on our own volition w/
protected
.While
private
& "package" are just plainly childish censorship. >:PI can't believe that I read that after PhiLho explained quite clearly the importance of controlling access and having private access modifiers.
Of course it's an important aspect when making a library for some strong typed language such as Java.
Although completely irrelevant for weak typed languages such as JavaScript & Python.
But repeating it again, do it via
protected
in place ofprivate
& "package".This way a class member is
protected
against "accidental" access.And at the same time, still allows conscious "patch" for libraries via inheritance or anonymous instantiation! :-B
Thanks for the clarification, so we are agreed that
is just plainly inaccurate :)