9. Visibility Lesson¶
Visibility¶
Visibility
Lesson Objectives
Introduce visibility using UML diagrams that illustrate a code base that starts small and gets larger over time. In each part, we will introduce one of Java’s four visibility options by incorporating it into one or places in the code base, then explore the impact of those changes.
Part 1: Getting Started
Rapid Fire Review
For each line marked with a comment below, write down whether each entity declaration is a top-level, member-level, or local-level declaration.
1package cs1302.social; 2 3public class Person { // <------------------------- LINE1 4 5 private String name; // <----------------------- LINE2 6 7 public Person(String name) { // <--------------- LINE3 8 int x = 42; // <----------------------------- LINE4 9 setName(name); 10 } // Person 11 12 public String getName() { // <------------------ LINE5 13 return name; 14 } // getName 15 16 protected void setName(String name) { // <------ LINE6 17 this.name = name; // <------- LINE7 18 } // getName 19 20} // Person
In the table below, replace each
?with a Yes/No indicating where each entity declaration is visible from.Entity
Visible From
Declared As
Same Class
Same Package
Child Class
Elsewhere
public
?
?
?
?
protected
?
?
?
?
package private
?
?
?
?
private
?
?
?
?
Why Visibility?
Developers of Java incorporated visibility into the language “to prevent the users of a package or class from depending on unnecessary details of the implementation of that package or class.”
Why Visibility?
How does visibility relate to encapsulation?
How might visibility relate to security?
Who benefits from visibility?
Evolving UML
How many classes are depicted?
How many packages are depicted?
How many public entities do you see?
How many protected entities do you see?
How many package private entities do you see?
How many private entities do you see?
How many classes are depicted?
How many packages are depicted?
How many public entities do you see?
How many protected entities do you see?
How many package private entities do you see?
How many private entities do you see?
For each package private entity you see, explain why you believe the developers made the decision to make those entities package private.
How many classes, interfaces, or enums are depicted?
How many packages are depicted?
Do you see any public entities?
Do you see any protected entities?
Do you see any package private entities?
Do you see any private entities?
For each package private entity you see, explain why you believe the developers made the decision to make those entities package private.
What does the
Utilityclass look like?Is a
Utilityobject required to call its static methods?Why isn’t
Utilitycurrently being used?
Utility Class Declaration
1package cs1302.util;
2
3class Utility {
4
5 private Utility() {}
6
7 ...
8
9} // Utility
Part 2: Book
Book Copy Constructor
System.currentTimeMillis()
System and System.currentTimeMillis are both
public, and calling System.currentTimeMillis() is a
valid call from anywhere that will return with a
long value representing the current time. In
the examples here, we use it to make serial numbers;
however, other approaches are probably more appropriate
in practice.
ACTIVITY: For each potential copy constructor shown below, indicate if it is valid (will compile) or invalid (will not compile) – if it is invalid, then write down why:
1public Book(Book other) {
2 super(System.currentTimeMillis());
3 this.setTitle(other.title);
4} // Book
1public Book(Book other) {
2 super();
3 this.title = other.title;
4 this.serial = System.currentTimeMillis();
5} // Book
1public Book(Book other) {
2 super();
3 this.title = other.title;
4 this.setSerial(other.getSerial());
5} // Book
Solution
Version 1: Will not compile because the
Productconstructor does not take any arguments. When we pass an argument tosuper, the compiler will not be able to find that constructor.Version 2: The first two lines will work as expected. However, the
serialinstance variable inProductcannot be accessed directly from within theBookclass because it is package private.Version 3: This compiles and properly initializes both instance variables in the
Bookobject.
Code Interpretation
ACTIVITY: Each of the following lines are already in
BookDriver. for each line below, copy it
down, then indicate if it is valid (will compile) or invalid
(will not compile) – if it is invalid, then write down why:
1Book b = new Book("Lord of the Rings");
2InventoryManager im = new InventoryManager();
3System.out.println(b);
4b.setTitle("The Great Gatsby");
5InventoryManager.nullCheck("main", b);
6im.addItem(b);
7im.requestPurchase(b);
8im.search(b);
9im.approvePurchase(b);
Solution
Valid
Invalid: the
InventoryManagerconstructor is private in theInventoryManagerclass.Valid
Invalid: the
setTitlemethod is private in theBookclass.Invalid: the
nullCheckmethod is private in theInventoryManagerclass.Invalid. The
addItemmethod is package private in theInventoryManagerclass.Valid
Valid
Invalid. The
approvePurchasemethod is package private in theInventoryManagerclass.
Discussion
If we moved the code in the previous activity to InventoryDriver, would our
answers be the same?
Solution
Lines 6 and 9 would be valid in this scenario because they
would be able to access package private methods in the cs1302.inventory
package.
Part 3: InventoryDriver
Code Interpretation 1
ACTIVITY: Each of the following lines are already in
InventoryDriver. for each line below, copy it
down, then indicate if it is valid (will compile) or invalid
(will not compile) – if it is invalid, then write down why:
1Book b = new Book("Lord of the Rings");
2b.setTitle("1984");
3System.out.println(b.getTitle());
4Product p = new Book("The Great Gatsby");
5System.out.println(p.getTitle());
6System.out.println(p);
7p.setSerial(14);
8p.serial = 14;
Solution
Valid
Invalid: the
setTitlemethod is private in theBookclass.Valid
Valid
Invalid: the
getTitlemethod cannot be called on a reference of typeProductsinceProductdoes not contain that method. While this is invalid, the reason is not related to visibility.Valid
Valid
Valid
Bonus Practice: How would the answers change if we moved
this code to BookDriver.main?
Code Interpretation 2
ACTIVITY: Each of the following lines are already in
InventoryDriver. for each line below, copy it
down, then indicate if it is valid (will compile) or invalid
(will not compile) – if it is invalid, then write down why:
1// we already know the next two lines are valid
2Book b = new Book("Lord of the Rings");
3Product p = new Book("The Great Gatsby");
4
5// start the activity with the next line
6InventoryManager im = InventoryManager.getManager();
7im.addItem(p);
8im.requestPurchase(p);
9InventoryManager.nullCheck("main", p);
10im.search(b);
11im.approvePurchase(b);
Solution
Valid
Valid
Valid
Invalid: The
nullcheckmethod is private in theInventoryManagerclass.Valid
Valid
Bonus Practice: How would the answers change if we moved
this code to BookDriver.main?
Part 4: Discussion
Does anyone have any additional visibility-related questions regarding this UML diagram?
Discussion 1
Can the
InventoryManagerchange the serial number of the product inaddItemeither directly or viasetSerial?Can the
InventoryManager addItemmethod call theProductconstructor?Can the
InventoryManager addItemmethod call thegetSerialmethod inProduct?
Solution
Yes, you can call
setSerialfromaddItemsinceaddItemis in the same package.No, because the
Productconstructor can only be called from a child class usingsuper. This is not related to visibility.Yes
Discussion 2
Look up some protected methods in String using the
following command:
javap java.lang.String | grep indexOf
Note
You can add -private to also see private entities.
You should see 2 indexOf methods that are used internally. The
users of the String class don’t need to understand how to use
those methods - they are meant for internal use.
Remember, visibility is used “to prevent the users of a package or class from depending on unnecessary details of the implementation of that package or class.”