Chapter 7: Beyond Classes Flashcards
Which of the following are valid record declarations?
public record A (int i) { private static final int i = 1; }
public final record B (int i) { }
public abstract record C () { private static int i; }
public record D (boolean b) {
@Override public boolean b() { return false;}
}
public record E (long i) {
@Override public boolean equals(Object obj) {
return false; }
public void setSize(long i) {
this.i = i; }
}
public final record B (int i) { }
public record D (boolean b) {
@Override public boolean b() { return false;}
}
A doesn’t, as it declares a static field with the same name as an instance field
records are implicitly final and cannot be marked abstract (looking at you, C).
records aren’t required to declare any fields.
Records may override any accessor methods.
Records are immutable so any mutator methods that modify methods aren’t allowed (E).
What can be inserted to make it compile?
interface A {}
public class B implements A {
main() {
____ b = new D();
} }
class C extends B { }
class D extends B { }
A, B, D or var
the blank can be filled with any class or interface that is a supertype of D
B is the direct supertype of D, and D is the same class, so both are correct
D inherits A, so A is correct
a var is permitted when the type is known
What is the result?
public class A {
enum X {
ALPHA, BRAVO, CHARLIE
static final X DEFAULT = ALPHA; }
main() {
for (final var e : X.values())
print( e.ordinal() + “” )
}
}
One line doesn’t compile
When an enum only contains a list of values, the semicolon after the list is optional . When an enum contains anything else e.g. a constructor or a variable, you have to include the semicolon.
If the semicolon were included, the code would print 0 1 2 at runtime.
public sealed class X permits Y {
public X (int i) {}
@Override public String toString() { return “string” ; }
main(String[] a) {
var b = new Y(10, null);
print b; } }
class Y extends X {
@Override public String toString() { return “none” ; }
public Y (int i, String s) { super(i); } }
does not compile
A class extending a sealed class must be marked final, sealed or non-sealed. Since Y is missing any of those, it won’t compile.
interface A { double size s = 1.0f; abstract int getM(); } abstract class B implements A { abstract int getN() } public class C extends B { int getM(int i) { return 1; } int getN() { return 6; } }
does not compile because of
public class C extends B
abstract method getM isn’t properly overridden, the overriding class fails to compile as it is the class itself that was supposed to have a no-args getM() method
public abstract interface X {
int i = 10; public void a();
public abstract int b() { return 1; }
}
abstract class Y extends X {
Object a(int p) { return null; }
}
won’t compile because of
public abstract int b() {return 1;}
Since an abstract method cannot include a body.
&
abstract class Y extends X
wrong keyword, should be implements
interface A { int getN( int p ); }
public class B implements A {
String getS() { return “S”; }
int getN (int p2) { return 1; }
main {
print( new B().getN(-1)); } }
won’t compile because of int getN (int p2) { return 1; }
The inherited interface getN(int) is implicitly public hence must be declared public in any concrete class that implements the interface.
Since the method uses the package (default) modifier in B, i.e. int getN (int p2) { return 1; }
, it won’t compile
public class A { \_\_\_\_ int n = 0; \_\_\_\_ void multiply() { n *= 6; } \_\_\_ int getN() { return n } }
- private, public and public
- private, protected and private
- private, private and protected
Instance variables must include the private access modifier. While it is common for methods to be public, this is not required.
’ The book is emphasizing encapsulation, which is one of the core principles of Object-Oriented Programming (OOP). It suggests that the instance variables should be private to protect the data and ensure that it cannot be accessed directly from outside the class. Methods can have various access modifiers depending on the requirements. ‘
e.g. protected, meaning it can be accessed within the same package or by subclasses.
private = just the class
abstract class A {} class B extends A {} class C extends B {} public class X { private A a; public void setA (A myA) { this.a = myA; } main { new X().setA(\_\_\_); } }
- new B
- new C
- null
the setA() method requires an instance of A. B is a direct subclass, while C is an indirect subclass. So B and C are OK.
String is an unrelated subclass, Object is a superclass, so it can’t be those.
Finally, a null value can always be passed as an object value, regardless of type.
interface A { private static List move() return {null;}} interface B extends A { public ArrayList move(); } class C implements A { public \_\_\_ move() { return null; } } class D implements B { public \_\_\_ move() { return null; } }
Integer, ArrayList or List for C
ArrayList for D
A defines a private method not inherited in any of it’s subtypes. For this reason, any valid class is supported for C (the answers above were just multiple choice answers).
For D, only ArrayList or subtypes of ArrayList are supported.
public class X { private int i = 5; private X() {} protected class Y() { public static int i = 10; public void startX() { print i ; } } main { var x = new X(); X.Y in = new X().new Y(); in.startX(); } }
output is 10
Starting with Java 16, inner classes can contain static variables, so the code compiles. Remember that private constructors can be used by any methods within the outer class.
The i
referred to in Y is the static variable.
1.
What is true about encapsulation?
Encap allows methods to get and set instance variables so oher classes are not directly using them. Instance variables must be private for this to work.
public class X {
enum A { ALPHA, BRAVO, CHARLIE }
main {
A a = null;
switch(a) {
case a.ALPHA -> print (“a”);
case a.BRAVO -> print (“b”);
case a.CHARLIE -> print (“c”);
default-> print (“missing data”);
}
}
More than one line does not compile
When using an enum in a switch expression, the case statement must be made up of the enum values only. If the enum name is used in the case statement value, then code does not compile.
ALPHA is acceptable but a.ALPHA is not
so the 3 case statements do not compile.
If they were fixed, the code would compile and produce a NPE at runtime
What is true about sealed classes?
A sealed interface restricts which subinterface may extend it or implement it
A sealed class can’t be extended by an abstract classs
What will allow the code print “a” at runtime/
public class G { public static void a() {print ("a") } protected final class H { public static void a() {print ("a2") } public static void main(String... x) { var g = new G().newH() {}; \_\_\_\_\_\_\_\_; }
The code does not compile
H is final. so it can’t be extended
The main method uses an anonymous class that inherits from H, which is not allowed.
If H wasn’t final, then
* new G().a()
* G.a()
would work to print “a” while g.a() would print “a2”