Chapter 7 Methods and Encapsulation Notes Flashcards

1
Q

Method declaration

A
public final void nap(int minutes) throws InterruptedException {
    // take a nap
}
  1. access modifier (optional)
  2. optional specifier (optional)
  3. return type (required)
  4. method name (required)
  5. parentheses (required)
  6. list of parameters (can be empty)
  7. exception (optional)
  8. method body (can be emtpy, body omitted for abstract methods)

Two of the parts—the method name and parameter list—are called the method signature.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

ACCESS MODIFIERS

A
  1. The private modifier means the method can be called only from within the same class.
  2. Default (Package-Private) Access With default access, the method can be called only from classes in the same package. This one is tricky because there is no keyword for default access. You simply omit the access modifier.
  3. The protected modifier means the method can be called only from classes in the same package or subclasses. You’ll learn about subclasses in Chapter 8, “Class Design.”
  4. The public modifier means the method can be called from any class.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

> [!NOTE:]
There’s a default keyword in Java. You saw it in the switch statement and interfaces.
It’s not used for access control.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Valid?

public void walk1() {}
default void walk2() {} // DOES NOT COMPILE
void public walk3() {} // DOES NOT COMPILE
void walk4() {}
A
  • The walk2() method doesn’t compile because default is not a valid access modifier.
  • The walk3() method doesn’t compile because the access modifier is specified after the return type.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

OPTIONAL SPECIFIERS

A
  1. The static modifier is used for class methods and will be covered later in this chapter.
  2. The abstract modifier is used when a method body is not provided. It will be covered in Chapter 9.
  3. The final modifier is used when a method is not allowed to be overridden by a subclass. It will also be covered in Chapter 8.
  4. The synchronized modifier is used with multithreaded code. It is on the 1Z0-816 exam, but not the 1Z0-815 exam.
  5. The native modifier is used when interacting with code written in another language such as C++. It is not on either OCP 11 exam.
  6. The strictfp modifier is used for making floating-point calculations portable. It is not on either OCP 11 exam.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q
public void walk1() {}
public final void walk2() {}
public static final void walk3() {}
public final static void walk4() {}
public modifier void walk5() {} // DOES NOT COMPILE
public void final walk6() {} // DOES NOT COMPILE
final public void walk7() {}
A
  • The walk5() method doesn’t compile because modifier is not a valid optional specifier.
  • The walk6() method doesn’t compile because the optional specifier is after the return type.
  • The walk7() method does compile. Java allows the optional specifiers to appear before the access modifier.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

> [!NOTE:]
Remember that a method must have a return type.
If no value is returned, the return type is void.
You cannot omit the return type.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
public void walk1() {}
public void walk2() { return; }
public String walk3() { return ""; }
public String walk4() {} // DOES NOT COMPILE
public walk5() {} // DOES NOT COMPILE
public String int walk6() { } // DOES NOT COMPILE
String walk7(int a) { if (a == 4) return ""; } // DOES NOT COMPILE
A
  • The walk4() method doesn’t compile because the return statement is missing.
  • The walk5() method doesn’t compile because the return type is missing.
  • The walk6() method doesn’t compile because it attempts to use two return types. You get only one return type.
  • The walk7() method is a little tricky. There is a return statement, but it doesn’t always get run. If a is 6, the return statement doesn’t get executed. Since the String always needs to be returned, the compiler complains.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q
int integer() {
    return 9;
}
int longMethod() {
    return 9L; // DOES NOT COMPILE
}
int integerExpanded() {
    int temp = 9;
    return temp;
}
int longExpanded() {
    int temp = 9L; // DOES NOT COMPILE
    return temp;
}
A

can’t return a long primitive in a method that returns an int.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
public void walk1() {}
public void 2walk() {} // DOES NOT COMPILE
public walk3 void() {} // DOES NOT COMPILE
public void Walk_$() {}
public _() {} // DOES NOT COMPILE
public void() {} // DOES NOT COMPILE
A
  • The 2walk() method doesn’t compile because identifiers are not allowed to begin with numbers.
  • The walk3() method doesn’t compile because the method name is before the return type.
  • The Walk_$() method is a valid declaration. While it certainly isn’t good practice to start a method name with a capital letter and end with punctuation, it is legal.
  • The _ method is not allowed since it consists of a single underscore.
  • The final line of code doesn’t compile because the method name is missing.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
public void walk1() {}
public void walk2 {} // DOES NOT COMPILE
public void walk3(int a) {}
public void walk4(int a; int b) {} // DOES NOT COMPILE
public void walk5(int a, int b) {}
A
  • The walk2() method doesn’t compile because it is missing the parentheses around the parameter list.
  • The walk4() method doesn’t compile because the parameters are separated by a semicolon rather than a comma. Semicolons are for separating statements, not for parameter lists.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
public void zeroExceptions() {}
public void oneException() throws IllegalArgumentException {}
public void twoExceptions() throws IllegalArgumentException, InterruptedException {}
A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q
public void walk1() {}
public void walk2() // DOES NOT COMPILE
public void walk3(int a) { int name = 5; }
A

The walk2() method doesn’t compile because it is missing the braces around the empty method body.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Working with Varargs

A
  • a method may use a varargs parameter (variable argument) as if it is an array.
  • A varargs parameter must be the last element in a method’s parameter list. This means you are allowed to have only one varargs parameter per method.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q
public void walk1(int... nums) {}
public void walk2(int start, int... nums) {}
public void walk3(int... nums, int start) {} // DOES NOT COMPILE
public void walk4(int... start, int... nums) {} // DOES NOT COMPILE
A

The walk3() and walk4() methods do not compile because they have a varargs parameter in a position that is not the last one.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Can you figure out why each method call outputs what it does?

15: public static void walk(int start, int... nums) {
16:     System.out.println(nums.length);
17: }
18: public static void main(String[] args) {
19:     walk(1); // 0
20:     walk(1, 2); // 1
21:     walk(1, 2, 3); // 2
22:     walk(1, new int[] {4, 5}); // 2
23: }
walk(1, null); // throws a NullPointerException in walk()
A
  • Line 19 passes 1 as start but nothing else. This means Java creates an **array of length 0 for nums. **
  • Line 20 passes **1 as start **and one more value. Java converts this one value to **an array of length 1. **
  • Line 21 passes 1 as start and two more values. Java converts these two values to an array of length 2.
  • Line 22 passes 1 as start and an array of length 2 directly as nums.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q
16: public static void run(int... nums) {
17:     System.out.println(nums[1]);
18: }
19: public static void main(String[] args) {
20:     run(11, 22); // 22
21: }
A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Applying Access Modifiers

A
  • private: Only accessible within the same class
  • Default (package-private) access: private plus other classes in the same package
  • protected: Default access plus child classes
  • public: protected plus classes in the other packages
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

> [!NOTE:]
The Java module system redefines “anywhere,” and it becomes possible to restrict access to public code. When given a code sample, you can assume it isn’t in a module unless explicitly stated otherwise.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

> [!NOTE:]
Remember to look at the reference type for a variable when you see a static method or variable. The exam creators will try to trick you into thinking a NullPointerException is thrown because the variable happens to be null. Don’t be fooled!

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

A static method or instance method can call a static method because static methods don’t require an object to use. Only an instance method can call another instance method on
the same class without using a reference variable, because instance methods do require an object. Similar logic applies for the instance and static variables.

A
22
Q

STATIC INITIALIZATION

A

instance initializers that looked like unnamed methods—just code inside braces. Static initializers look similar. They add the static keyword to specify they should be run when the class is first loaded.

All static initializers run when the class is first used in the order they are defined. The statements in them run and assign any static variables as needed.

23
Q
14: private static int one;
15: private static final int two;
16: private static final int three = 3;
17: private static final int four; // DOES NOT COMPILE
18: static {
19:     one = 1;
20:     two = 2;
21:     three = 3; // DOES NOT COMPILE
22:     two = 4; // DOES NOT COMPILE
23: }
A
  • Line 14 declares a static variable that is not final. It can be assigned as many times as we like.
  • Line 15 declares a final variable without initializing it. This means we can initialize it exactly once in a static block. Line 22 doesn’t compile because this is the second attempt.
  • Line 16 declares a final variable and initializes it at the same time. We are not allowed to assign it again, so line 21 doesn’t compile.
  • Line 17 declares a final variable that never gets initialized. The compiler gives a compiler error because it knows that the static blocks are the only place the variable could possibly get initialized. Since the programmer forgot, this is clearly an error.
24
Q

TRY TO AVOID STATIC AND INSTANCE INITIALIZERS

A

Using static and instance initializers can make your code much harder to read. Everything that could be done in an instance initializer could be done in a constructor instead. Many people find the constructor approach is easier to read.

There is a common case to use a static initializer: when you need to initialize a static field and the code to do so requires more than one line. This often occurs when you want to initialize a collection like an ArrayList. When you do need to use a static initializer, put all the static initialization in the same block. That way, the order is obvious.

25
Q

> [!NOTE:]
In a large program, static imports can be overused. When importing from too many places, it can be hard to remember where each static member comes from.

A
26
Q

STATIC IMPORTS

A

Static imports are for importing static members of classes. Just like regular imports, you can use a wildcard or import a specific member. The idea is that you shouldn’t have to specify where each static method or variable comes from each time you use it. An example of when static imports shine is when you are referring to a lot of constants in another class.

27
Q
import java.util.List;
import static java.util.Arrays.asList; // static import
public class StaticImports {
    public static void main(String[] args) {
        List<String> list = asList("one", "two"); // no Arrays.
    }
}
A

In this example, we are specifically importing the asList method. This means that any time we refer to asList in the class, it will call Arrays.asList().

28
Q
1: import static java.util.Arrays; // DOES NOT COMPILE
2: import static java.util.Arrays.asList;
3: static import java.util.Arrays.*; // DOES NOT COMPILE
4: public class BadStaticImports {
5:     public static void main(String[] args) {
6:         Arrays.asList("one"); // DOES NOT COMPILE
7: } }
A
  • Line 1 tries to use a static import to import a class. Remember that static imports are only for importing static members. Regular imports are for importing a class.
  • Line 3 tries to see whether you are paying attention to the order of keywords. The syntax is import static and not vice versa.
  • Line 6 is sneaky. The asList method is imported on line 2. However, the Arrays class is not imported anywhere. This makes it okay to write asList(“one”) but not Arrays.asList(“one”).
29
Q
import static statics.A.TYPE;
import static statics.B.TYPE; // DOES NOT COMPILE
A

The compiler will complain if you try to explicitly do a static import of two methods with the same name or two static variables with the same name.

Luckily, when this happens, we can just refer to the static members via their class name in the code instead of trying to use a static import.

30
Q

Java is a “pass-by-value” language. This means that a copy of the variable is made and the method receives that copy.

A
31
Q
2: public static void main(String[] args) {
3:     int num = 4;
4:     newNumber(num);
5:     System.out.println(num); // 4
6: }
7: public static void newNumber(int num) {
8:     num = 8;
9: }
A
  • On line 3, num is assigned the value of 4.
  • On line 4, we call a method.
  • On line 8, the num parameter in the method gets set to 8. Although this parameter has the same name as the variable on line 3, this is a coincidence. The name could be anything. The exam will often use the same name to try to confuse you.
  • The variable on line 3 never changes because no assignments are made to it.
32
Q
public static void main(String[] args) {
String name = "Webby";
speak(name);
System.out.println(name);
}
public static void speak(String name) {
name = "Sparky";
}
A

The correct answer is Webby.
The variable assignment is only to the method parameter and doesn’t affect the caller.

33
Q
public static void main(String[] args) {
StringBuilder name = new StringBuilder();
speak(name);
System.out.println(name); // Webby
}
public static void speak(StringBuilder s) {
s.append("Webby");
}
A

Both point to the same StringBuilder, which means that changes made to the StringBuilder are available to both references.

34
Q
1: public class ReturningValues {
2: public static void main(String[] args) {
3: int number = 1; // number=1
4: String letters = "abc"; // letters=abc
5: number(number); // number=1
6: letters = letters(letters); // letters=abcd
7: System.out.println(number + letters); // 1abcd
8: }
9: public static int number(int number) {
10: number++;
11: return number;
12: }
13: public static String letters(String letters) {
14: letters += "d";
15: return letters;
16: }
A
  • Lines 3 and 4 are straightforward assignments.
  • Line 5 calls a method. Line 10 increments the method parameter to 2 but leaves the number variable in the main() method as 1.
  • While line 11 returns the value, the caller ignores it. The method call on line 6 doesn’t ignore the result, so letters becomes “abcd”.
  • Remember that this is happening because of the returned value and not the method parameter.
35
Q

Overloading Methods

A

Method overloading occurs when methods have the same name but different method signatures, which means they differ by method parameters.

we can overload by changing anything in the parameter list. We can have a different type, more types, or the same types in a different order. Also notice that the return type, access modifier, and exception list are irrelevant to overloading.

36
Q

These are all valid overloaded methods:

public void fly(int numMiles) {}
public void fly(short numFeet) {}
public boolean fly() { return false; }
void fly(int numMiles, short numFeet) {}
public void fly(short numFeet, int numMiles) throws Exception {}
A
  • we can overload by changing anything in the parameter list.
  • We can have a different type, more types, or the same types in a different order.
  • Also notice that the return type, access modifier, and exception list are irrelevant to overloading.
37
Q
public void fly(int numMiles) {}
public int fly(int numMiles) {} // DOES NOT COMPILE
A

This method doesn’t compile because it differs from the original only by return type. The parameter lists are the same, so they are duplicate methods as far as Java is concerned.

38
Q

Why does the second not compile?

public void fly(int numMiles) {}
public static void fly(int numMiles) {} // DOES NOT COMPILE
A

the parameter list is the same. You cannot have methods where the only difference is that one is an instance method and one is a static method.

39
Q

Which method do you think is called if we pass an int[]?

public void fly(int[] lengths) {}
public void fly(int... lengths) {} // DOES NOT COMPILE
A

Trick question! Remember that Java treats varargs as if they were an array. This means that the method signature is the same for both methods. Since we are not allowed to overload methods with the same parameter list, this code doesn’t compile. Even though the code doesn’t look the same, it compiles to the same parameter list.

40
Q

fly(3), will call which method?

public void fly(int numMiles) {}
public void fly(Integer numMiles) {}
A

Java will match the int numMiles version. Java tries to use the most specific parameter list it can find. When the primitive int version isn’t present, it will autobox. However, when the primitive int version is provided, there is no reason for Java to do the extra work of autoboxing.

41
Q

what do you think this code outputs?

public class ReferenceTypes {
    public void fly(String s) {
        System.out.print("string");
    }
    public void fly(Object o) {
        System.out.print("object");
    }
    public static void main(String[] args) {
        ReferenceTypes r = new ReferenceTypes();
        r.fly("test");
        System.out.print("-");
        r.fly(56);
    }
}
A

The answer is string-object.
The first call is a String and finds a direct match. There’s no reason to use the Object version when there is a nice String parameter list just waiting to be called. The second call looks for an int parameter list. When it doesn’t find one, it autoboxes to Integer. Since it still doesn’t find a match, it goes to the Object one.

42
Q

What does this print?

public static void print(Iterable i) {
    System.out.print("I");
}
public static void print(CharSequence c) {
    System.out.print("C");
}
public static void print(Object o) {
    System.out.print("O");
}
public static void main(String[] args){
    print("abc");
    print(new ArrayList<>());
    print(LocalDate.of(2019, Month.JULY, 4));
}
A
  • The answer is CIO. The code is due for a promotion!
  • The first call to print() passes a String. As you learned in Chapter 5, String and StringBuilder implement the CharSequence interface.
  • The second call to print() passes an ArrayList. Remember that you get to assume unknown APIs do what they sound like. In this case, Iterable is an interface for classes you can iterate over.
  • The final call to print() passes a LocalDate. This is another class you might not know, but that’s okay. It clearly isn’t a sequence of characters or something to loop through. That means the Object method signature is used.
43
Q

What do you think happens here?

public class Plane {
public void fly(int i) {
System.out.print("int");
}
public void fly(long l) {
System.out.print("long");
}
public static void main(String[] args) {
Plane p = new Plane();
p.fly(123);
System.out.print("-");
p.fly(123L);
}
}
A
  • The answer is int-long.
  • The first call passes an int and sees an exact match.
  • The second call passes a long and also sees an exact match. If we comment out the overloaded method with the int parameter list, the output becomes long-long. Java has no problem calling a larger primitive. However, it will not do so unless a better match is not found.
  • Note that Java can only accept wider types. An int can be passed to a method taking a long parameter. Java will not automatically convert to a narrower type. If you want to pass a long to a method taking an int parameter, you have to add a cast to explicitly say narrowing is okay.
44
Q
public void walk(List<String> strings) {}
public void walk(List<Integer> integers) {} // DOES NOT COMPILE
A

Java has a concept called type erasure where generics are used only at compile time.

45
Q
public void walk(List strings) {}
public void walk(List integers) {} // DOES NOT COMPILE
A

We clearly can’t have two methods with the same method signature, so this doesn’t compile. Remember that method overloads must differ in at least one of the method parameters.

46
Q

this code is just fine:

public static void walk(int[] ints) {}
public static void walk(Integer[] integers) {}
A

Arrays have been around since the beginning of Java. They specify their actual types and don’t participate in type erasure.

47
Q

The order that Java uses to choose the right overloaded method

A

Example of what will be chosen for glide(1,2)
1. Exact match by type
String glide(int i, int j)
2. Larger primitive type
String glide(long i, long j)
3. Autoboxed type String
glide(Integer i, Integer j)
4. Varargs String
glide(int... nums)

48
Q

What do you think this outputs?

public class Glider2 {
public static String glide(String s) {
return "1";
}
public static String glide(String... s) {
return "2";
}
public static String glide(Object o) {
return "3";
}
public static String glide(String s, String t) {
return "4";
}
public static void main(String[] args) {
System.out.print(glide("a"));
System.out.print(glide("a", "b"));
System.out.print(glide("a", "b", "c"));
}
}
A

It prints out 142.
* The first call matches the signature taking a single String because that is the most specific match.
* The second call matches the signature, taking two String parameters since that is an exact match.
* It isn’t until the third call that the varargs version is used since there are no better matches.

49
Q
public class TooManyConversions {
public static void play(Long l) {}
public static void play(Long... l) {}
public static void main(String[] args) {
play(4); // DOES NOT COMPILE
play(4L); // calls the Long version
}
}
A

Here we have a problem. Java is happy to convert the int 4 to a long 4 or an Integer 4.
It cannot handle converting to a long and then to a Long. If we had public static void play(Object o) {}, it would match because only one conversion would be necessary: from int to Integer.
Remember, if a variable is not a primitive, it is an Object, as you’ll see in Chapter 8.

50
Q

Encapsulating Data

A

Encapsulation means only methods in the class with the variables can refer to the instance variables. Callers are required to use these methods.

For encapsulation, remember that data (an instance variable) is private and getters/setters are public.

ex:
~~~
1: public class Swan {
2: private int numberEggs; // private
3: public int getNumberEggs() { // getter
4: return numberEggs;
5: }
6: public void setNumberEggs(int newNumber) { // setter
7: if (newNumber >= 0) // guard condition
8: numberEggs = newNumber;
9: } }
~~~

51
Q

Naming conventions for getters and setters

A

1. Getter methods most frequently begin with is if the property is a boolean.
~~~
public boolean isHappy() {
return happy;
}
~~~
2. Getter methods begin with get if the property is not a boolean.
~~~
public int getNumberEggs() {
return numberEggs;
}
~~~
3. Setter methods begin with set.
~~~
public void setHappy(boolean _happy) {
happy = _happy;
}
~~~