Warning
You are mixing two related questions.
Questions:
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
[2] In both cases, which access modifiers, should apply ?
Short Quick Answer
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
Go, for the "fields access by accessor methods" a.k.a. "getter (s) and setter (s)". The other method is NOT wrong, it depends, what do you want to do.
[2] In both cases, which access modifiers, should apply ?
If you go for "plain fields", use "public", unless there is an specific reason to use "private" or "protected". If you go for "accesors methods", use "protected" for the fields, and "protected" or "public" for the accesors.
Long Boring Extended Answer
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
Go, for the "fields access by accessor methods" a.k.a. "getter (s) and setter (s)".
The other method is NOT wrong, it depends, what do you want to do.
But, since property access can be overriden by those methods, that allows more features to be added, removed or changed by methods.
I suggest, leave "plain fields" for Data Objects.
[2] In both cases, which access modifiers, should apply ?
If you go for "plain fields", use "public", unless there is an specific reason to use "private" or "protected".
If you go for "accesors methods", use "protected" for the fields, and "protected" or "public" for the accesors.
Is not a good idea to apply "public" access for accesors' fields, because this way, you confuse yourself and other programmer users of your classes,
on which one to directly use.
Code Example:
public class ControlClass {
// example of non private field (s)
protected String controlname;
// ...
// example of non private field (s)
protected int width;
protected int height;
// ...
// example of read-only property
public final String getControlName()
{
return this.controlname;
} // String getControlName(...)
// ...
@Override
public int getWidth()
{
return this.width;
} // int getWidth(...)
@Override
public void setWidth(int newvalue)
{
this.width = newvalue;
} // void setWidth(...)
@Override
public int getHeight()
{
return this.height;
} // int getHeight(...)
@Override
public void setHeight(int newvalue)
{
this.height = newvalue;
} // void setHeight(...)
// ...
// constructor assigns initial values to properties' fields
public ControlClass(){
this.controlname = "control";
this.height = 0;
this.width = 0;
} // ControlClass(...)
// ...
} // class ControlClass
public class ButtonClass extends ControlClass {
// ...
// example of overriden public property with non public field
@Override
public int getWidth()
{
if (this.width < 5)
return 5
else
return this.width;
} // int getWidth(...)
// example of overriden public property with non public field
@Override
public void setWidth(int newvalue)
{
if (newvalue < 5)
throw new ArithmeticException("integer underflow");
this.width = newvalue;
} // void setWidth(...)
// example of overriden public property with non public field
@Override
public int getHeight()
{
if (this.height < 5)
return 5
else
return this.height;
} // int getHeight(...)
// example of overriden public property with non public field
@Override
public void setHeight(int newvalue)
{
if (newvalue < 5)
throw new ArithmeticException("integer underflow");
this.height = newvalue;
} // void setHeight(...)
// ...
// constructor assigns initial values to properties' fields
public ControlClass(){
this.controlname = "ButtonClass";
this.height = 5;
this.width = 5;
} // ButtonClass(...)
// ...
} // class ControlClass
I started to use "private" for fields, like many programmers, buy, eventually, had to change to "protected", because sometimes required to use it. directly.
Additional Comment.
I have work with other object oriented programming languages, with its own way and syntax for "properties", and that's give you another perspective.
Such as Object Pascal ( a.k.a. "Delphi" ), ECMAScript ( "Javascript" ), C++, C#. Note that Delphi and C#, supports "full properties", not just accesors methods or fields, and that's give developer another way of designing an Object and Class Oriented Software Application.
What does this has to do with Java ?
We'll when I design a Class in Java or C++, I design properties, the same way, as C# or Delphi, does, a concept that is independent of fields, or methods, even if there can be implemented by them.
Cheers.