Chapter 9 Advanced Class Design Notes Flashcards

Advanced Class Design

1
Q

Creating Abstract Classes

A

test

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

INTRODUCING ABSTRACT CLASSES

A
  • An abstract class is a class that cannot be instantiated and may contain abstract methods.
  • An abstract method is a method that does not define an implementation when it is declared.
  • Both abstract classes and abstract methods are denoted with the abstract modifier.
abstract class Bird {
    public abstract String getName();
    public void printName() {
        System.out.print(getName());
    }
}
public class Stork extends Bird {
    public String getName() { return "Stork!"; }
    public static void main(String[] args) {
        new Stork().printName();
    }
}

In particular, the Stork class must now override the abstract getName() method.

For example, the following implementation does not compile because Stork does not override the required abstract getName() method:

public class Stork extends Bird {} // DOES NOT COMPILE

An abstract class is most commonly used when you want another class to inherit properties of a particular class, but you want the subclass to fill in some of the implementation details.

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

OVERRIDE VS. IMPLEMENT

A
  • Oftentimes, when an abstract method is overridden in a subclass, it is referred to as implementing the method.
  • It is described this way because the subclass is providing an implementation for a method that does not yet have one.
  • While we tend to use the terms implement and override interchangeably for abstract methods, the term override is more accurate.
  • When overriding an abstract method, all of the rules you learned about overriding methods in Chapter 8 are applicable.

An abstract class can be initialized, but only as part of the instantiation of a nonabstract subclass.

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

DEFINING ABSTRACT METHODS

A
  • An abstract class may include nonabstract methods, in this case with the printName() method.
  • In fact, an abstract class can include all of the same members as a nonabstract class, including variables, static and instance methods, and inner classes.
  • As you will see in the next section, abstract classes can also include constructors.
  • One of the most important features of an abstract class is that it is not actually required to include any abstract methods. For example, the following code compiles even though it doesn’t define any abstract methods:
public abstract class Llama {
    public void chew() {}
}
  • Although an abstract class doesn’t have to declare any abstract methods, an abstract method can only be defined in an abstract class (or an interface, as you will see shortly)
public class Egret { // DOES NOT COMPILE
    public abstract void peck();
}
  • Like the final modifier, the abstract modifier can be placed before or after the access modifier in class and method declarations, as shown in this Tiger class:
abstract public class Tiger {
    abstract public int claw();
}
  • There are some restrictions on the placement of the abstract modifier. The abstract modifier cannot be placed after the class keyword in a class declaration, nor after the return type in a method declaration. The following Jackal and howl() declarations do not compile for these reasons:
public class abstract Jackal { // DOES NOT COMPILE
    public int abstract howl(); // DOES NOT COMPILE
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

> [!NOTE]
It is not possible to define an abstract method that has a body, or default implementation.
You can still define a method with a body—you just can’t mark it as abstract.
As long as you do not mark the method as final, the subclass has the option to override an inherited method.

A

cannot define body or default implementation for abstract method

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

Constructors in Abstract Classes

A

Even though abstract classes cannot be instantiated, they are still initialized through constructors by their subclasses. For example, does the following program compile?

abstract class Bear {
    abstract CharSequence chew();
    public Bear() {
        System.out.println(chew()); // Does this compile?
    }
}
public class Panda extends Bear {
    String chew() { return "yummy!"; }
    public static void main(String[] args) {
        new Panda();
    }
}

Using the constructor rules you learned in Chapter 8, the compiler inserts a default no-argument constructor into the Panda class, which first calls super() in the Bear class. The Bear constructor is only called when the abstract class is being initialized through a subclass; therefore, there is an implementation of chew() at the time the constructor is called. This code compiles and prints yummy! at runtime.

For the exam, remember that abstract classes are initialized with constructors in the same way as nonabstract classes. For example, if an abstract class does not provide a constructor, the compiler will automatically insert a default no-argument constructor.

The primary difference between a constructor in an abstract class and a nonabstract class is that a constructor in abstract class can be called only when it is being initialized by a nonabstract subclass. This makes sense, as abstract classes cannot be instantiated.

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

Invalid Abstract Method Declarations

public abstract class Turtle {
    public abstract long eat() // DOES NOT COMPILE
    public abstract void swim() {}; // DOES NOT COMPILE
    public abstract int getAge() { // DOES NOT COMPILE
        return 10;
    }
    public void sleep; // DOES NOT COMPILE
    public void goInShell(); // DOES NOT COMPILE
}
A
  • The first method, eat(), does not compile because it is marked abstract but does not end with as semicolon (;).
  • The next two methods, swim() and getAge(), do not compile because they are marked abstract, but they provide an implementation block enclosed in braces ({}).
  • The next method, sleep, does not compile because it is missing parentheses, (), for method arguments.
  • The last method, goInShell(), does not compile because it is not marked abstract and therefore must provide a body enclosed in braces.
  • For the exam, remember that an abstract method declaration must end in a semicolon without any braces.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Invalid Modifiers

A

In this section, we review the abstract modifier and which modifiers it is not compatible with.

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

abstract and final Modifiers

A
  • If you mark something abstract, you are intending for someone else to extend or implement it.
  • But, if you mark something final, you are preventing anyone from extending or implementing it.
  • These concepts are in direct conflict with each other.

Due to this incompatibility, Java does not permit a class or method to be marked both abstract and final. For example, the following code snippet will not compile:

public abstract final class Tortoise { // DOES NOT COMPILE
    public abstract final void walk(); // DOES NOT COMPILE
}

The exam doesn’t tend to use final modifiers on classes or methods often, so if you see them, make sure they aren’t used with the abstract modifier.

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

abstract and private Modifiers

A
  • A method cannot be marked as both abstract and private.
  • This rule makes sense if you think about it.
  • How would you define a subclass that implements a required method if the method is not inherited by the subclass?
  • The answer is you can’t, which is why the compiler will complain if you try to do the following:
public abstract class Whale {
    private abstract void sing(); // DOES NOT COMPILE
}
public class HumpbackWhale extends Whale {
    private void sing() {
        System.out.println("Humpback whale is singing");
    }
}
  • In this example, the abstract method sing() defined in the parent class Whale is not visible to the subclass HumpbackWhale.
  • Even though HumpbackWhale does provide an implementation, it is not considered an override of the abstract method since the abstract method is not inherited.
  • The compiler recognizes this in the parent class and reports an error as soon as private and abstract are applied to the same method.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

If we changed the access modifier from private to protected in the parent class Whale, would the code compile? Let’s take a look:

public abstract class Whale {
    protected abstract void sing();
}
public class HumpbackWhale extends Whale {
    private void sing() { // DOES NOT COMPILE
        System.out.println("Humpback whale is singing");
    }
}

In this modified example, the code will still not compile, but for a completely different reason. If you remember the rules for overriding a method, the subclass cannot reduce the visibility of the parent method, sing(). Because the method is declared protected in the parent class, it must be marked as protected or public in the child class. Even with abstract methods, the rules for overriding methods must be followed.

A

test

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

> [!NOTE]
While it is not possible to declare a method abstract and private,
it is possible (albeit redundant) to declare a method final and private.

A

test

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

abstract and static Modifiers

A
  • A static method cannot be overridden.
  • It is defined as belonging to the class, not an instance of the class.
  • If a static method cannot be overridden, then it follows that it also cannot be marked abstract since it can never be implemented. For example, the following class does not compile:
abstract class Hippopotamus {
abstract static void swim(); // DOES NOT COMPILE
}

For the exam, make sure you know which modifiers can and cannot be used with one another, especially for abstract classes and interfaces.

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

CREATING A CONCRETE CLASS

A
  • An abstract class becomes usable when it is extended by a concrete subclass.
  • A concrete class is a nonabstract class.
  • The first concrete subclass that extends an abstract class is required to implement all inherited abstract methods.
  • This includes implementing any inherited abstract methods from inherited interfaces, as we will see later in this chapter.
  • When you see a concrete class extending an abstract class on the exam, check to make sure that it implements all of the required abstract methods.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

REVIEWING ABSTRACT CLASS RULES

A

Abstract Class Definition Rules
1. Abstract classes cannot be instantiated.
2. All top-level types, including abstract classes, cannot be marked protected or private.
3. Abstract classes cannot be marked final.
4. Abstract classes may include zero or more abstract and nonabstract methods.
5. An abstract class that extends another abstract class inherits all of its abstract methods.
6. The first concrete class that extends an abstract class must provide an implementation for all of the inherited abstract methods.
7. Abstract class constructors follow the same rules for initialization as regular constructors, except they can be called only as part of the initialization of a subclass.

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

Abstract Method Definition Rules

A

Abstract Method Definition Rules
1. Abstract methods can be defined only in abstract classes or interfaces.
2. Abstract methods cannot be declared private or final.
3. Abstract methods must not provide a method body/implementation in the abstract class in which they are declared.
4. Implementing an abstract method in a subclass follows the same rules for overriding a method, including covariant return types, exception declarations, etc.

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

Implementing Interfaces

A
  • Although Java doesn’t allow multiple inheritance of state,
  • it does allow a class to implement any number of interfaces.
  • An interface is an abstract data type are that declares a list of abstract methods that any class implementing the interface must provide.
  • An interface can also include constant variables.
  • Both abstract methods and constant variables included with an interface are implicitly assumed to be public.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

INTERFACES AND NONABSTRACT METHODS

A
  • For the 1Z0-815 exam, you only need to know about two members for interfaces: abstract methods and constant variables.
  • With Java 8, interfaces were updated to include static and default methods.
  • A default method is one in which the interface method has a body and is not marked abstract.
  • It was added for backward compatibility, allowing an older class to use a new version of an interface that contains a new method, without having to modify the existing class.
  • In Java 9, interfaces were updated to support private and private static methods.
  • Both of these types were added for code reusability within an interface declaration and cannot be called outside the interface definition.
  • When you study for the 1Z0-816 exam, you will need to know about other kinds of interface members.
  • For the 1Z0-815 exam, you only need to know about abstract methods and constant variables.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

DEFINING AN INTERFACE

A
public abstract interface CanBurrow {
    public abstract Float getSpeed(int age);
    public static final int MINIMUM_DEPTH = 2;
  1. public or default (package-private) access modifier
  2. Implicit modifier (abstract)
  3. interface keyword
  4. Interface name
  5. Implicit modifiers (public abstract) - Abstract interface method
  6. Implicit modifiers (public static final) - Interface variable

One aspect of an interface declaration that differs from an abstract class is that it contains implicit modifiers. An implicit modifier is a modifier that the compiler automatically adds to a class, interface, method, or variable declaration.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q
public abstract interface WalksOnTwoLegs {}
A
  • It compiles because interfaces are not required to define any methods.
  • The abstract modifier in this example is optional for interfaces, with the compiler inserting it if it is not provided.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q
public class Biped {
    public static void main(String[] args) {
        var e = new WalksOnTwoLegs(); // DOES NOT COMPILE
    }
}

public final interface WalksOnEightLegs {} // DOES NOT COMPILE
A
  • The first example doesn’t compile, as WalksOnTwoLegs is an interface and cannot be instantiated.
  • The second example, WalksOnEightLegs, doesn’t compile because interfaces cannot be marked as final for the same reason that abstract classes cannot be marked as final. In other words, marking an interface final implies no class could ever implement it.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

How do you use an interface?

A

test

23
Q

Implementing an interface

A
public class FieldMouse implements Climb, CanBurrow {
    public Float getSpeed(int age) {
		    return 11f;
		}
}
  1. Class name
  2. implements keyword (required)
  3. Interface name(s) separated by commas (,)
  4. public keyword (required)
  5. Covariant return type
  6. Signature matches interface method
24
Q

Many of the rules for class declarations also apply to interfaces including the following :

  • A Java file may have at most one public top-level class or interface, and it must match the name of the file.
  • A top-level class or interface can only be declared with public or package-private access.

It may help to think of an interface as a specialized abstract class, as many of the rules carry over. Just remember that an interface does not follow the same rules for single inheritance and instance initialization with constructors, as a class does.

A

test

25
Q

Like a class, an interface can extend another interface using the extends keyword.

A
interface Nocturnal {}

public interface HasBigEyes extends Nocturnal {}
26
Q

An interface can extend multiple interfaces.

A
interface Nocturnal {
    public int hunt();
}
interface CanFly {
    public void flap();
}
interface HasBigEyes extends Nocturnal, CanFly {}
public class Owl implements Nocturnal, CanFly {
    public int hunt() { return 5; }
    public void flap() { System.out.println("Flap!"); }
}
27
Q

WHAT ABOUT ENUMS?

A
  • This public top-level element could also be an enumeration, or enum for short.
  • An enum is a specialized type that defines a set of fixed values.
  • It is declared with the enum keyword.
public enum Color {
    RED, YELOW, BLUE, GREEN, ORANGE, PURPLE
}

Like classes and interfaces, enums can have more complex formations including methods, private constructors, and instance variables.

28
Q

INSERTING IMPLICIT MODIFIERS

A

The following list includes the implicit modifiers for interfaces that you need to know for the exam:

  • Interfaces are assumed to be abstract.
  • Interface variables are assumed to be public, static, and final.
  • Interface methods without a body are assumed to be abstract and public.
public interface Soar {
    int MAX_HEIGHT = 10;
    final static boolean UNDERWATER = true;
    void fly(int speed);
    abstract void takeoff();
    public abstract double dive();
}

public abstract interface Soar {
    public static final int MAX_HEIGHT = 10;
    public final static boolean UNDERWATER = true;
    public abstract void fly(int speed);
    public abstract void takeoff();
    public abstract double dive();
}
29
Q

Conflicting Modifiers

A
public interface Dance {
    private int count = 4; // DOES NOT COMPILE
    protected void step(); // DOES NOT COMPILE
}

public interface Sing {
    float volume = 10;
    abstract void start();
}

Cannot mark method or variable with protected or private modifier.
as the compiler will apply the public modifier to both, resulting in a conflict.

public interface Sing {
    float volume = 10;
    abstract void start();
}

omitting the access modifier indicates default (package-private) access.
When working with interface members, though, the lack of access modifier always indicates public access. (implicit modifier)

30
Q
1: private final interface Crawl {
2: String distance;
3: private int MAXIMUM_DEPTH = 100;
4: protected abstract boolean UNDERWATER = false;
5: private void dig(int depth);
6: protected abstract double depth();
7: public final void surface(); }
A

Every single line of this example, including the interface declaration, does not compile!

  • Line 1 does not compile for two reasons.
    • First, it is marked as final, which cannot be applied to an interface since it conflicts with the implicit abstract keyword.
    • Next, it is marked as private, which conflicts with the public or package-private access for top-level interfaces.
  • Line 2 does not compile because the distance variable is not initialized. Remember that interface variables are assumed to be static final constants and initialized when they are declared.
  • Lines 3 and 4 do not compile because interface variables are also assumed to be public, and the access modifiers on these lines conflict with this.
  • Line 4 also does not compile because variables cannot be marked abstract.
  • Next, lines 5 and 6 do not compile because all interface abstract methods are assumed to be public and marking them as private or protected is not permitted.
  • Finally, the last line doesn’t compile because the method is marked as final, and since interface methods without a body are assumed to be abstract, the compiler throws an exception for using both abstract and final keywords on a method.
31
Q

Differences between Interfaces and Abstract Classes

A

Even though abstract classes and interfaces are both considered abstract types, only interfaces make use of implicit modifiers. This means that an abstract class and interface with similar declarations may have very different properties.

abstract class Husky {
    abstract void play();
}

interface Poodle {
    void play();
}
  • The Husky class will not compile if the play() method is not marked abstract,
  • whereas the method in the Poodle interface will compile with or without the abstract modifier.
  • The play() method in Husky class is considered default (package-private),
  • whereas the method in the Poodle interface is assumed to be public.
class Webby extends Husky {
    void play() {}
}
class Georgette implements Poodle {
   void play() {}
}
  • The Webby class compiles,
  • but the Georgette class does not.
  • Even though the two method implementations are identical, the method in the Georgette class breaks the rules of method overriding.
  • From the Poodle interface, the inherited abstract method is assumed to be public.
  • The definition of play() in the Georgette class therefore reduces the visibility of a method from public to package-private, resulting in a compiler error.
  • The following is the correct implementation of the Georgette class:
class Georgette implements Poodle {
public void play() {}
}
32
Q

INHERITING AN INTERFACE

A

An interface can be inherited in one of three ways.
* An interface can extend another interface.
* A class can implement an interface.
* A class can extend another class whose ancestor implements an interface.

  • When an interface is inherited, all of the abstract methods are inherited.
  • Like we saw with abstract classes, if the type inheriting the interface is also abstract, such as an interface or abstract class, it is not required to implement the interface methods.
  • On the other hand, the first concrete subclass that inherits the interface must implement all of the inherited abstract methods.
33
Q

Mixing Class and Interface Keywords

A
  • The exam creators are fond of questions that mix class and interface terminology.
  • Although a class can implement an interface,
  • a class cannot extend an interface.
  • Likewise, while an interface can extend another interface,
  • an interface cannot implement another interface. The following examples illustrate these principles:
public interface CanRun {}
public class Cheetah extends CanRun {} // DOES NOT COMPILE
public class Hyena {}
public interface HasFur extends Hyena {} // DOES NOT COMPILE
  • The first example shows a class trying to extend an interface that doesn’t compile.
  • The second example shows an interface trying to extend a class, which also doesn’t compile.
  • Be wary of examples on the exam that mix class and interface definitions. The following is the only valid syntax for relating classes and interfaces in their declarations:
class1 extends class2
interface1 extends interface2, interface3, ...
class1 implements interface2, interface3, ...
34
Q

Duplicate Interface Method Declarations

A

Since Java allows for multiple inheritance via interfaces, you might be wondering what will happen if you define a class that inherits from two interfaces that contain the same abstract method.

public interface Herbivore {
    public void eatPlants();
}
public interface Omnivore {
    public void eatPlants();
    public void eatMeat();
}

In this scenario, the signatures for the two interface methods eatPlants() are duplicates. As they have identical method declarations, they are also considered compatible. By compatibility, we mean that the compiler can resolve the differences between the two declarations without finding any conflicts. You can define a class that fulfills both interfaces simultaneously.

public class Bear implements Herbivore, Omnivore {
    public void eatMeat() {
        System.out.println("Eating meat");
    }
    public void eatPlants() {
        System.out.println("Eating plants");
    }
}

As we said earlier, interfaces simply define a set of rules that a class implementing them must follow. If two abstract interface methods have identical behaviors—or in this case the same method declaration—you just need to be able to create a single method that overrides both inherited abstract methods at the same time.

35
Q

What if the duplicate methods have different signatures?

A

If the method name is the same but the input parameters are different, there is no conflict because this is considered a method overload. We demonstrate this principle in the following example:

public interface Herbivore {
    public int eatPlants(int quantity);
}
public interface Omnivore {
    public void eatPlants();
}
public class Bear implements Herbivore, Omnivore {
    public int eatPlants(int quantity) {
        System.out.println("Eating plants: "+quantity);
        return quantity;
    }
    public void eatPlants() {
        System.out.println("Eating plants");
    }
}

In this example, we see that the class that implements both interfaces must provide implementations of both versions of eatPlants(), since they are considered separate methods.

36
Q

What if the duplicate methods have the same signature but different return types?

A

In that case, you need to review the rules for overriding methods.
Let’s try an example:

interface Dances {
    String swingArms();
}
interface EatsFish {
    CharSequence swingArms();
}
public class Penguin implements Dances, EatsFish {
    public String swingArms() {
        return "swing!";
    }
}
  • In this example, the Penguin class compiles.
  • The Dances version of the swingArms() method is trivially overridden in the Penguin class, as the declaration in Dances and Penguin have the same method declarations.
  • The EatsFish version of swingArms() is also overridden as String and CharSequence are covariant return types.
37
Q

What if the duplicate methods have the same signature but different return types?

return types are not covariant

A

Let’s take a look at a sample where the return types are not covariant:

interface Dances {
    int countMoves();
}
interface EatsFish {
    boolean countMoves();
}
public class Penguin implements Dances, EatsFish { // DOES NOT COMPILE
...
}

Since it is not possible to define a version of countMoves() that returns both int and boolean, there is no implementation of the Penguin that will allow this declaration to compile. It is the equivalent of trying to define two methods in the same class with the same signature and different return types.

38
Q

test

A

The compiler would also throw an exception if you define an abstract class or interface that inherits from two conflicting abstract types, as shown here:

interface LongEars {
    int softSkin();
}
interface LongNose {
    void softSkin();
}
interface Donkey extends LongEars, LongNose {} // DOES NOT COMPILE
abstract class Aardvark implements LongEars, LongNose {} // DOES NOT COMPILE

All of the types in this example are abstract, with none being concrete. Despite the fact they are all abstract, the compiler detects that Donkey and Aardvark contain incompatible methods and prevents them from compiling.

39
Q

POLYMORPHISM AND INTERFACES

A

In Chapter 8, we introduced polymorphism and showed how an object in Java can take on many forms through references. While many of the same rules apply, the fact that a class can inherit multiple interfaces limits some of the checks the compiler can perform.

40
Q

Abstract Reference Types

A

When working with abstract types, you may prefer to work with the abstract reference types, rather than the concrete class. This is especially common when defining method parameters. Consider the following implementation:

Interface List<E>

import java.util.*;
public class Zoo {
    public void sortAndPrintZooAnimals(List<String> animals) {
        Collections.sort(animals);
        for(String a : animals) {
            System.out.println(a);
        }
    }
}

This class defines a method that sorts and prints animals in alphabetical order. At no point is this class interested in what the actual underlying object for animals is. It might be an ArrayList, which you have seen before, but it may also be a LinkedList or a Vector (neither of which you need to know for the exam).

41
Q

Casting Interfaces

A
  • Let’s say you have an abstract reference type variable, which has been instantiated by a concrete subclass.
  • If you need access to a method that is only declared in the concrete subclass, then you will need to cast the interface reference to that type, assuming the cast is supported at runtime.
  • That brings us back to a rule we discussed in Chapter 8, namely, that the compiler does not allow casts to unrelated types.
  • For example, the following is not permitted as the compiler detects that the String and Long class cannot be related:
String lion = "Bert";
Long tiger = (Long)lion; // DOSE NOT COMPILE
42
Q

With interfaces, there are limitations to what the compiler can validate. For example, does the following program compile?

1: interface Canine {}
2: class Dog implements Canine {}
3: class Wolf implements Canine {}
4:
5: public class BadCasts {
6: public static void main(String[] args) {
7: Canine canine = new Wolf();
8: Canine badDog = (Dog)canine;
9: } }
A
  • In this program, a Wolf object is created and then assigned to a Canine reference type on line 7.
  • Because of polymorphism, Java cannot be sure which specific class type the canine instance on line 8 is. Therefore, it allows the invalid cast to the Dog reference type, even though Dog and Wolf are not related.
  • The code compiles but throws a ClassCastException at runtime.
  • This limitation aside, the compiler can enforce one rule around interface casting. The compiler does not allow a cast from an interface reference to an object reference if the object type does not implement the interface. For example, the following change to line 8 causes the program to fail to compile:
8: Object badDog = (String)canine; // DOES NOT COMPILE

Since String does not implement Canine, the compiler recognizes that this cast is not possible.

43
Q

In Chapter 3, “Operators,” we showed that the compiler will report an error if you attempt to use the instanceof operator with two unrelated classes, as follows:

Number tickets = 4;
if(tickets instanceof String) {} // DOES NOT COMPILE
A

test

44
Q

Interfaces and the instanceof Operator

A

With interfaces, the compiler has limited ability to enforce this rule because even though a reference type may not implement an interface, one of its subclasses could. For example, the following does compile:

Number tickets = 5;
if(tickets instanceof List) {}

Even though Number does not inherit List, it’s possible the tickets variable may be a reference to a subclass of Number that does inherit List. As an example, the tickets variable could be assigned to an instance of

the following MyNumber class (assuming all inherited methods were implemented):

public class MyNumber extends Number implements List

That said, the compiler can check for unrelated interfaces if the reference is a class that is marked final.

Integer tickets = 6;
if(tickets instanceof List) {} // DOES NOT COMPILE

The compiler rejects this code because the Integer class is marked final and does not inherit List. Therefore, it is not possible to create a subclass of Integer that inherits the List interface.

45
Q

REVIEWING INTERFACE RULES

A

We summarize the interface rules in this part of the chapter in the following list. If you compare the list to our list of rules for an abstract class definition, the first four rules are similar.
1. Interface Definition Rules
Interfaces cannot be instantiated.
2. All top-level types, including interfaces, cannot be marked protected or private.
3. Interfaces are assumed to be abstract and cannot be marked final.
4. Interfaces may include zero or more abstract methods.
5. An interface can extend any number of interfaces.
6. An interface reference may be cast to any reference that inherits the interface, although this may produce an exception at runtime if the classes aren’t related.
7. The compiler will only report an unrelated type error for an instanceof operation with an interface on the right side if the reference on the left side is a final class that does not inherit the interface.
8. An interface method with a body must be marked default, private, static, or private static (covered when studying for the 1Z0-816 exam).

46
Q

Abstract Interface Method Rules

A
  1. Abstract methods can be defined only in abstract classes or interfaces.
  2. Abstract methods cannot be declared private or final.
  3. Abstract methods must not provide a method body/implementation in the abstract class in which is it declared.
  4. Implementing an abstract method in a subclass follows the same rules for overriding a method, including covariant return types, exception declarations, etc.
  5. Interface methods without a body are assumed to be abstract and public.
47
Q

Interface Variables Rules

A
  1. Interface variables are assumed to be public, static, and final.
  2. Because interface variables are marked final, they must be initialized with a value when they are declared.
48
Q

It may be helpful to think of an interface as a specialized kind of abstract class, since it shares many of the same properties and rules as an abstract class.

  • The primary differences between the two are that interfaces include
    • implicit modifiers,
    • do not contain constructors,
    • do not participate in the instance initialization process,
    • and support multiple inheritance.
A

test

49
Q

USING AN INTERFACE VS. IMPLEMENTING AN INTERFACE

A
  • An interface provides a way for one individual to develop code that uses another individual’s code, without having access to the other individual’s underlying implementation.
  • Interfaces can facilitate rapid application development by enabling development teams to create applications in parallel, rather than being directly dependent on each other.
  • For example, two teams can work together to develop a one-page standard interface at the start of a project.
  • One team then develops code that uses the interface, while the other team develops code that implements the interface.
  • The development teams can then combine their implementations toward the end of the project, and as long as both teams developed with the same interface, they will be compatible.
  • Of course, testing will still be required to make sure that the class implementing the interface behaves as expected.
50
Q

Introducing Inner Classes

A

test

51
Q

DEFINING A MEMBER INNER CLASS

A
  • A member inner class is a class defined at the member level of a class (the same level as the methods, instance variables, and constructors).
  • It is the opposite of a top-level class, in that it cannot be declared unless it is inside another class.
  • Developers often define a member inner class inside another class if the relationship between the two classes is very close.
  • For example, a Zoo sells tickets for its patrons; therefore, it may want to manage the lifecycle of the Ticket object.

The following is an example of an outer class Zoo with an inner class Ticket:

public class Zoo {
    public class Ticket {}
}

We can expand this to include an interface.

public class Zoo {
    private interface Paper {}
    public class Ticket implements Paper {}
}

While top-level classes and interfaces can only be set with public or package-private access, member inner classes do not have the same restriction. A member inner class can be declared with all of the same access modifiers as a class member, such as public, protected, default (package-private), or private.

A member inner class can contain many of the same methods and variables as a top-level class. Some members are disallowed in member inner classes, such as static members, although you don’t need to know that for the 1Z0-815 exam. Let’s update our example with some instance members.

public class Zoo {
private interface Paper {
    public String getId();
}
    public class Ticket implements Paper {
        private String serialNumber;
        public String getId() { return serialNumber;}
    }
}

Our Zoo and Ticket examples are starting to become more interesting. In the next section, we will show you how to use them.

52
Q

> [!NOTE]
For the 1Z0-816 exam, there are four types of nested classes you will need to know about:
member inner classes,
local classes,
anonymous classes,
and static nested classes.
You’ll also need to know more detail about member inner classes.
For this chapter, we limit our discussion to just the basics of member inner classes, as this is all you need to know on the 1Z0-815 exam.

A

four types of nested classes
1. member inner classes,
2. local classes,
3. anonymous classes,
4. static nested classes.

53
Q

USING A MEMBER INNER CLASS

A

One of the ways a member inner class can be used is by calling it in the outer class. Continuing with our previous example, let’s define a method in Zoo that makes use of the member inner class with a new sellTicket() method.

public class Zoo {
    private interface Paper {
        public String getId();
    }
    public class Ticket implements Paper {
        private String serialNumber;
        public String getId() { return serialNumber; }
    }
    public Ticket sellTicket(String serialNumber) {
        var t = new Ticket();
        t.serialNumber = serialNumber;
        return t;
    }
}

The advantage of using a member inner class in this example is that the Zoo class completely manages the lifecycle of the Ticket class. Let’s add an entry point to this example.

public class Zoo {
...
    public static void main(String... unused) {
        var z = new Zoo();
        var t = z.sellTicket("12345");
        System.out.println(t.getId()+" Ticket sold!");
    }
}

This compiles and prints 12345 Ticket sold! at runtime. For the 1Z0-815 exam, this is the extent of what you need to know about inner classes. As discussed, when you study for the 1Z0-816 exam, there is a lot more you will need to know.