-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAccessModifiers.java
More file actions
152 lines (133 loc) · 6.05 KB
/
Copy pathAccessModifiers.java
File metadata and controls
152 lines (133 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package Phase2_MethodsArraysStrings.Methods;
/**
* Access Modifiers in Java
* ------------------------
* Access modifiers control the VISIBILITY of classes, methods, fields, and
* constructors. Java has FOUR access levels:
* <p>
*
* Modifier | Same class | Same pkg | Subclass | World
* --------------+------------+----------+----------+-------
* public | YES | YES | YES | YES
* protected | YES | YES | YES | no
* (no modifier) | YES | YES | no | no
* (package- | | | |
* private) | | | |
* private | YES | no | no | no
* <p>
*
* Quick Rule Of Thumb
* -------------------
* - Default to `private` for fields and helper methods.
* - Expose `public` only for the API you intend callers to use.
* - Use `protected` when you specifically want subclasses to override or call.
* - Package-private (no modifier) is great for "internal to this package"
* helpers - not visible outside the package but more open than private.
* <p>
*
* Where Each Modifier May Appear
* ------------------------------
* CLASSES (top-level): only `public` or package-private. (Inner classes may
* also be private/protected.)
* METHODS : all four levels.
* FIELDS : all four levels.
* CONSTRUCT-: all four levels. A `private` constructor disables direct
* ORS instantiation (useful for utility classes and singletons).
* INTERFACE : interface methods are implicitly `public`. Java 9+ also allows
* MEMBERS `private` interface methods (helper code) - see InterfaceMethods.
* <p>
*
* Subtle Point - `protected` Across Packages
* ------------------------------------------
* A `protected` member is visible to a subclass in a different package, but
* ONLY through a reference of the subclass type (or its subtypes). Direct
* access via a parent-typed reference outside the package is not allowed.
* <p>
*
* This file demonstrates all four modifiers on a single Box class plus the
* common patterns (private fields + public getters/setters, private constructor
* for a singleton).
*/
public class AccessModifiers {
// === Demo class with all four access levels ===
static class Box {
public int publicField = 1; // visible everywhere
protected int protectedField = 2; // visible in package + subclasses
int packageField = 3; // visible in same package only
private int privateField = 4; // visible only inside Box
// Methods at each level
public void publicAction() { System.out.println("publicAction()"); }
protected void protectedAction() { System.out.println("protectedAction()"); }
void packageAction() { System.out.println("packageAction()"); }
private void privateAction() { System.out.println("privateAction()"); }
// A public method exposing private state via getters - classic encapsulation
public int getPrivateField() { return privateField; }
public void setPrivateField(int v) {
if (v < 0) throw new IllegalArgumentException("must be >= 0");
this.privateField = v;
}
// Public method that calls private helpers - private code is reusable
// INSIDE the class but invisible OUTSIDE.
public void process() {
privateAction();
System.out.println("processed, internal value = " + privateField);
}
}
// === A singleton using a private constructor ===
static class Singleton {
private static final Singleton INSTANCE = new Singleton();
private int counter = 0;
// private - blocks `new Singleton()` from outside
private Singleton() { }
public static Singleton getInstance() { return INSTANCE; }
public int next() { return ++counter; }
}
public static void main(String[] args) {
Box b = new Box();
// --- 1) Access from the SAME class (this main() lives in
// AccessModifiers, but Box is a nested static class) -
// because Box is inside AccessModifiers, we can still see
// all four levels. In a TRULY external class in a DIFFERENT
// package, only the public bits would be visible.
System.out.println("public = " + b.publicField);
System.out.println("protected = " + b.protectedField);
System.out.println("package = " + b.packageField);
System.out.println("private = " + b.privateField);
b.publicAction();
b.protectedAction();
b.packageAction();
b.privateAction();
// --- 2) Encapsulation: setter validates input ---
b.setPrivateField(42);
System.out.println("after set, privateField = " + b.getPrivateField());
try {
b.setPrivateField(-1); // setter rejects bad input
} catch (IllegalArgumentException e) {
System.out.println("setter rejected: " + e.getMessage());
}
// --- 3) public method internally orchestrates private helpers ---
b.process();
// --- 4) Singleton via private constructor ---
// new Singleton(); // ERROR - constructor is private
Singleton s = Singleton.getInstance();
System.out.println("singleton.next() = " + s.next());
System.out.println("singleton.next() = " + s.next());
System.out.println("same instance? = " + (s == Singleton.getInstance()));
// OUTPUT
// public = 1
// protected = 2
// package = 3
// private = 4
// publicAction()
// protectedAction()
// packageAction()
// privateAction()
// after set, privateField = 42
// setter rejected: must be >= 0
// privateAction()
// processed, internal value = 42
// singleton.next() = 1
// singleton.next() = 2
// same instance? = true
}
}