Advanced Class Flashcards

1
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
2
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
3
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
4
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
5
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
6
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
7
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
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
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();
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
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)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
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.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
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() {}
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
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.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
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, ...
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
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.

17
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.

18
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.
19
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.

20
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.

21
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

import java.util.*;
public class Zoo {
    public void sortAndPrintZooAnimals(List 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).

22
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
23
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.

24
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

25
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.

26
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).

27
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.
28
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.
29
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

30
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.
31
Q

Introducing Inner Classes

A

test

32
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.

33
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.

34
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.