1

After I learned to properly use private protected abstract sealed in a language like C# I found no reason to make a variable public ever again.

An interface to the variable is usually a public method if it is an action/verb (e.g. Car.Move()), or if it is a value/property of the class then I use property with a public getter and a private setter. (e.g. Car.Color which can only change on creation, but accessible anytime.)

If it is just a collection of values, its field still make more sense to be private and only assignable on creation via the constructor.

I want to know some situations which a common practice is to make a public variable if you have any to share.

  • Hi 5argon! Just a question. What do you mean by public variable? A public instance attribute? Or public class attribute? – Laiv Mar 23 '18 at 14:35
6

Any time you are doing interop with C or other languages, you will often find you need to do all kinds of things considered unsavory in OOP. Using classes with public variables is often one of them.

Also, even when working entirely in a single language, sometimes you want what are effectively mutable structs, and going to the effort of creating hidden fields and visible accessors is a hassle of seemingly no value. Sure, sometimes tooling or language features make the hassle pretty low but not 0.

2

It's generally considered safe and reasonable to use public variables when they're immutable, i.e. constants. In Java its quite commonplace to see this kind of thing:

public final class Direction {

    public static final String NORTH = "north";
    public static final String SOUTH = "south";
    public static final String EAST = "east";
    public static final String WEST = "west";

}

But just to add a bit of food for thought, I would contest that this kind of thing is redundant:

public class Person {

     private int age;
     private String name;

     public void setAge(int age) { this.age = age; }
     public int getAge(){ return age; }
     public void setName(String name) { this.name = name; }
     public String getName() { return this.name; } 

}

Of course it adheres to a convention which is widely accepted as correct, but it appears to miss the point of encapsulation for reasons which are documented excellently in this article, I thoroughly recommend you give it a read :)

  • 1
    How is this answering the question: "When is reasonable to use public variables?" – Laiv Mar 23 '18 at 7:30
  • I've given an example of when it's acceptance to use public variables and also added some critical thinking which I think will cement his/her understanding of encapsulation. – J Smith Mar 23 '18 at 12:46
  • Well, I would not consider static constants to be "variables", neither OOP – Laiv Mar 23 '18 at 13:44
  • Firstly, 'static' is an important OOP concept, and secondly, constants are just a special type of variable that you can't change. – J Smith Mar 23 '18 at 13:53
  • I have the feeling OP is trying to figure when myInstance.instanceAttribute can be public and variable (being the attribute mutable). Your answer is more or less "never", but that's an ambitious claim – Laiv Mar 23 '18 at 14:25
1

Value types should almost always have public variables. Say you've got a type like the following (C++, but really could be any language):

struct Point {
  int x;
  int y;
}

Making it immutable just means you allocate all the time (you're going to be modifying the object a lot, after all). Adding accessors and mutators serves no purpose and substantially complicates use of the class. Just have public members!

As a case study, in version 1.8 of Minecraft the game moved to passing coordinates around as an immutable class instead of three doubles, and the result was significant performance issues due to GC stuttering.

  • But that's an implementation detail. In Swift, I'd expect a 3d point to be exactly as efficient as three numbers. Not requiring any non-stack allocation, and there is no GC that could stutter :-) – gnasher729 Apr 6 '18 at 13:06
  • @gnasher729 then the question is "Do I want my points to be immutable?". I would argue there are many cases where the answer for this sort of simple value type is "no", in which case you've got public variables. (The example is a specific case where immutable reference types used as value types led to disaster. Implementation details are important if performance matters, which it does more than people credit) – James Picone Apr 7 '18 at 14:22
0

I cannot think of a sensible situation, outside extreme performance dedicated code. It may be a requirement of some framework to expose variables/properties publicly (like Java implicitly does with anotated properties in JPA).

I think it not very maintainable to expose public variables/properties because you let the using classes rely on specific things. What if a public integer needs to be changed to a long for some reason? All using classes need to be changed. Then there is also the notion of (im)mutability. A using class does not want to know or check whether a variable/property is 'readonly' or 'const' (I guess these are what is 'final' in Java). Because if they (have to) know this, they know a lot more of the used class then they would when everything was encapsulated. Why would we like using classes to know as little about others as possible? Again maintainability and S from the SOLID principles.

  • "All using classes need to be changed [if an int changes to a long]" - and this is perfectly fine and reasonable if all of the using classes are contained within one project. – immibis Apr 6 '18 at 3:28
  • I think you are right, but it depends on the project size. I would as a rule of thumb not want to change more than 20 classes because of such a change. And big chances are fine BTW, but you should try not to overdo it and redesign your API every month. – RabbitBones22 Apr 6 '18 at 5:16
0

The only time is use public on field deceleration is when declaring public static and final fields (constants).

If the field represents immutable shared item, I don't see why we shouldn't use public.

  • 2
    The only time? I don't think so. – immibis Apr 6 '18 at 3:27
0

There are some object oriented programming languages that don't even support public variables - including Smalltalk, which is often cited as the primary originator of the object oriented programming concept. If these languages can get away without this feature without it being seen as a problematic omission (and I've never really seen that opinion being common - there are problems with Smalltalk that have prevented it ever becoming truly popular, but this isn't one of them), then I think the answer must be either "never" or at least close to it. You can use public variables as a shortcut to avoid the need to provide getters and setters, but there is no need to do so, and because there is a negative consequence (increased coupling to the internal design of the class) I would suggest that sacrificing design for brevity in this way is not often a good idea.

(Note that this doesn't apply in languages that provide public properties, e.g. C#, which are syntactically like public variables but allow for a change of implementation without changing the public interface of the class, so do not have negative consequences in the same way)

protected by gnat Apr 6 '18 at 7:04

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.