Advanced Class Flashcards
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 }
- The first method,
eat()
, does not compile because it is markedabstract
but does not end with as semicolon (;). - The next two methods,
swim()
andgetAge()
, do not compile because they are markedabstract
, 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 markedabstract
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.
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.
test
REVIEWING ABSTRACT CLASS RULES
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.
Abstract Method Definition Rules
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.
DEFINING AN INTERFACE
public abstract interface CanBurrow { public abstract Float getSpeed(int age); public static final int MINIMUM_DEPTH = 2;
public
ordefault
(package-private) access modifier- Implicit modifier (
abstract
) interface
keyword- Interface name
- Implicit modifiers (
public abstract
) - Abstract interface method - 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.
public abstract interface WalksOnTwoLegs {}
- 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.
Implementing an interface
public class FieldMouse implements Climb, CanBurrow { public Float getSpeed(int age) { return 11f; } }
- Class name
- implements keyword (required)
- Interface name(s) separated by commas (,)
- public keyword (required)
- Covariant return type
- Signature matches interface method
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 orpackage-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.
test
WHAT ABOUT ENUMS?
- 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.
INSERTING IMPLICIT MODIFIERS
The following list includes the implicit modifiers for interfaces that you need to know for the exam:
-
Interfaces
are assumed to beabstract
. -
Interface variables
are assumed to bepublic, static, and final
. -
Interface methods
without a body are assumed to beabstract 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(); }
Conflicting Modifiers
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)
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(); }
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 implicitabstract
keyword. - Next, it is marked as
private
, which conflicts with thepublic
orpackage-private
access for top-level interfaces.
- First, it is marked as
- 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.
Differences between Interfaces and Abstract Classes
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() {} }
INHERITING AN INTERFACE
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.
Mixing Class and Interface Keywords
- 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, ...